From 50b77de328b73beacb24f18453358566df27797e Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Sat, 9 Jun 2012 15:14:25 +0200 Subject: [PATCH] added the crash server handler library Based on TortoiseSVN rev. 22970 Signed-off-by: Sven Strickroth --- ext/CrashServer/CommonLibs/Log/log.cpp | 1120 ++ ext/CrashServer/CommonLibs/Log/log.h | 418 + ext/CrashServer/CommonLibs/Log/log_media.h | 68 + ext/CrashServer/CommonLibs/Log/synchro.h | 82 + ext/CrashServer/CommonLibs/Version/version.h | 83 + ext/CrashServer/CommonLibs/Version/version.rc | 105 + ext/CrashServer/CommonLibs/Zlib/ZipUnzip.cpp | 166 + ext/CrashServer/CommonLibs/Zlib/ZipUnzip.h | 51 + ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj | 180 + .../CommonLibs/Zlib/Zlib.vcxproj.filters | 138 + .../CommonLibs/Zlib/Zlib_static.vcxproj | 180 + ext/CrashServer/CrashHandler/COPYING | 674 + ext/CrashServer/CrashHandler/COPYING.LESSER | 165 + .../CrashHandler/CrashHandler/CrashHandler.cpp | 587 + .../CrashHandler/CrashHandler/CrashHandler.def | 11 + .../CrashHandler/CrashHandler/CrashHandler.h | 320 + .../CrashHandler/CrashHandler/CrashHandler.rc | 58 + .../CrashHandler/CrashHandler/CrashHandler.vcxproj | 307 + .../CrashHandler/CrashHandler.vcxproj.filters | 65 + .../CrashHandler/CrashHandler/CrashHandlerExport.h | 41 + .../CrashHandler/CrashHandler/projectinfo.h | 26 + .../CrashHandler/CrashHandler/resource.h | 16 + .../CrashHandler/CrashHandler/stdafx.cpp | 18 + ext/CrashServer/CrashHandler/CrashHandler/stdafx.h | 32 + .../CrashHandler/CrashHandler/targetver.h | 23 + .../DumpUploaderServiceLib.vcxproj | 141 + .../DumpUploaderServiceLib.vcxproj.filters | 57 + .../DumpUploaderWebService.cpp | 81 + .../DumpUploaderWebService.h | 31 + .../generated/DumpUploader.h | 1225 ++ .../generated/UploaderSoap.nsmap | 15 + .../generated/UploaderSoap12.nsmap | 15 + .../DumpUploaderServiceLib/generated/soapC.cpp | 6279 ++++++++ .../DumpUploaderServiceLib/generated/soapH.h | 1479 ++ .../DumpUploaderServiceLib/generated/soapStub.h | 546 + .../generated/soapUploaderSoap12Proxy.cpp | 294 + .../generated/soapUploaderSoap12Proxy.h | 61 + .../generated/soapUploaderSoapProxy.cpp | 294 + .../generated/soapUploaderSoapProxy.h | 61 + .../DumpUploaderServiceLib/gsoapWinInet-2.8.0.cpp | 1185 ++ .../DumpUploaderServiceLib/gsoapWinInet.cpp | 1432 ++ .../DumpUploaderServiceLib/gsoapWinInet.h | 200 + .../DumpUploaderServiceLib/make_service_stub.bat | 12 + .../DumpUploaderServiceLib/typemap.dat | 210 + ext/CrashServer/CrashHandler/SendRpt/Config.h | 48 + ext/CrashServer/CrashHandler/SendRpt/CrashInfo.cpp | 85 + ext/CrashServer/CrashHandler/SendRpt/CrashInfo.h | 17 + .../CrashHandler/SendRpt/CrashProcessor.cpp | 981 ++ .../CrashHandler/SendRpt/DumpWriter.cpp | 121 + ext/CrashServer/CrashHandler/SendRpt/DumpWriter.h | 54 + .../CrashHandler/SendRpt/SendReportDlg.cpp | 167 + .../CrashHandler/SendRpt/SendReportDlg.h | 208 + ext/CrashServer/CrashHandler/SendRpt/SendRpt.cpp | 59 + ext/CrashServer/CrashHandler/SendRpt/SendRpt.ico | Bin 0 -> 3638 bytes ext/CrashServer/CrashHandler/SendRpt/SendRpt.rc | 311 + .../CrashHandler/SendRpt/SendRpt.vcxproj | 230 + .../CrashHandler/SendRpt/SendRpt.vcxproj.filters | 93 + .../CrashHandler/SendRpt/SendRptM.vcxproj | 231 + .../CrashHandler/SendRpt/SendRptM.vcxproj.filters | 91 + .../CrashHandler/SendRpt/Serializer.cpp | 132 + ext/CrashServer/CrashHandler/SendRpt/Serializer.h | 49 + .../CrashHandler/SendRpt/dbghelp_x64.dll | Bin 0 -> 1369936 bytes .../CrashHandler/SendRpt/dbghelp_x86.dll | Bin 0 -> 1080656 bytes ext/CrashServer/CrashHandler/SendRpt/projectinfo.h | 26 + ext/CrashServer/CrashHandler/SendRpt/resource.h | 36 + ext/CrashServer/CrashHandler/SendRpt/stdafx.cpp | 18 + ext/CrashServer/CrashHandler/SendRpt/stdafx.h | 29 + ext/CrashServer/CrashHandler/SendRpt/targetver.h | 23 + ext/CrashServer/CrashHandler/crashhandler.props | 27 + ext/CrashServer/CrashHandler/crashhandler.sln | 80 + ext/CrashServer/CrashHandler/solutioninfo.h | 29 + ext/CrashServer/Readme.txt | 3 + ext/CrashServer/SymUpload.exe | Bin 0 -> 306176 bytes ext/CrashServer/external/MiniZip/MiniZip.vcxproj | 160 + ext/CrashServer/external/WTL/CPL.TXT | 94 + ext/CrashServer/external/WTL/Include/atlapp.h | 1690 ++ ext/CrashServer/external/WTL/Include/atlctrls.h | 10039 ++++++++++++ ext/CrashServer/external/WTL/Include/atlctrlx.h | 4827 ++++++ ext/CrashServer/external/WTL/Include/atlgdi.h | 3850 +++++ ext/CrashServer/external/WTL/Include/atlres.h | 262 + ext/CrashServer/external/WTL/Include/atluser.h | 1193 ++ ext/CrashServer/external/WTL/Include/atlwinx.h | 529 + .../mod_gsoap/gsoap_win/wininet/gsoapWinInet.h | 196 + .../external/gsoap-win32-2.8.0/stdsoap2.cpp | 15822 +++++++++++++++++++ .../external/gsoap-win32-2.8.0/stdsoap2.h | 2472 +++ ext/CrashServer/external/zlib123/README | 125 + ext/CrashServer/external/zlib123/adler32.c | 149 + ext/CrashServer/external/zlib123/compress.c | 79 + .../external/zlib123/contrib/minizip/crypt.h | 132 + .../external/zlib123/contrib/minizip/ioapi.c | 177 + .../external/zlib123/contrib/minizip/ioapi.h | 75 + .../external/zlib123/contrib/minizip/iowin32.c | 270 + .../external/zlib123/contrib/minizip/iowin32.h | 21 + .../external/zlib123/contrib/minizip/mztools.c | 281 + .../external/zlib123/contrib/minizip/unzip.c | 1598 ++ .../external/zlib123/contrib/minizip/unzip.h | 354 + .../external/zlib123/contrib/minizip/zip.c | 1219 ++ .../external/zlib123/contrib/minizip/zip.h | 235 + ext/CrashServer/external/zlib123/crc32.c | 423 + ext/CrashServer/external/zlib123/crc32.h | 441 + ext/CrashServer/external/zlib123/deflate.c | 1736 ++ ext/CrashServer/external/zlib123/deflate.h | 331 + ext/CrashServer/external/zlib123/gzio.c | 1026 ++ ext/CrashServer/external/zlib123/infback.c | 623 + ext/CrashServer/external/zlib123/inffast.c | 318 + ext/CrashServer/external/zlib123/inffast.h | 11 + ext/CrashServer/external/zlib123/inffixed.h | 94 + ext/CrashServer/external/zlib123/inflate.c | 1368 ++ ext/CrashServer/external/zlib123/inflate.h | 115 + ext/CrashServer/external/zlib123/inftrees.c | 329 + ext/CrashServer/external/zlib123/inftrees.h | 55 + ext/CrashServer/external/zlib123/trees.c | 1219 ++ ext/CrashServer/external/zlib123/trees.h | 128 + ext/CrashServer/external/zlib123/uncompr.c | 61 + ext/CrashServer/external/zlib123/zconf.h | 332 + ext/CrashServer/external/zlib123/zlib.h | 1357 ++ ext/CrashServer/external/zlib123/zutil.c | 318 + ext/CrashServer/external/zlib123/zutil.h | 269 + 118 files changed, 78103 insertions(+) create mode 100644 ext/CrashServer/CommonLibs/Log/log.cpp create mode 100644 ext/CrashServer/CommonLibs/Log/log.h create mode 100644 ext/CrashServer/CommonLibs/Log/log_media.h create mode 100644 ext/CrashServer/CommonLibs/Log/synchro.h create mode 100644 ext/CrashServer/CommonLibs/Version/version.h create mode 100644 ext/CrashServer/CommonLibs/Version/version.rc create mode 100644 ext/CrashServer/CommonLibs/Zlib/ZipUnzip.cpp create mode 100644 ext/CrashServer/CommonLibs/Zlib/ZipUnzip.h create mode 100644 ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj create mode 100644 ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj.filters create mode 100644 ext/CrashServer/CommonLibs/Zlib/Zlib_static.vcxproj create mode 100644 ext/CrashServer/CrashHandler/COPYING create mode 100644 ext/CrashServer/CrashHandler/COPYING.LESSER create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.cpp create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.def create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.h create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.rc create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj.filters create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/CrashHandlerExport.h create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/projectinfo.h create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/resource.h create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/stdafx.cpp create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/stdafx.h create mode 100644 ext/CrashServer/CrashHandler/CrashHandler/targetver.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj.filters create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.cpp create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/DumpUploader.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap.nsmap create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap12.nsmap create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapC.cpp create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapH.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapStub.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.cpp create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.cpp create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet-2.8.0.cpp create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.cpp create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.h create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/make_service_stub.bat create mode 100644 ext/CrashServer/CrashHandler/DumpUploaderServiceLib/typemap.dat create mode 100644 ext/CrashServer/CrashHandler/SendRpt/Config.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/CrashInfo.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/CrashInfo.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/CrashProcessor.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/DumpWriter.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/DumpWriter.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRpt.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRpt.ico create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRpt.rc create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj.filters create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj create mode 100644 ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj.filters create mode 100644 ext/CrashServer/CrashHandler/SendRpt/Serializer.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/Serializer.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/dbghelp_x64.dll create mode 100644 ext/CrashServer/CrashHandler/SendRpt/dbghelp_x86.dll create mode 100644 ext/CrashServer/CrashHandler/SendRpt/projectinfo.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/resource.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/stdafx.cpp create mode 100644 ext/CrashServer/CrashHandler/SendRpt/stdafx.h create mode 100644 ext/CrashServer/CrashHandler/SendRpt/targetver.h create mode 100644 ext/CrashServer/CrashHandler/crashhandler.props create mode 100644 ext/CrashServer/CrashHandler/crashhandler.sln create mode 100644 ext/CrashServer/CrashHandler/solutioninfo.h create mode 100644 ext/CrashServer/Readme.txt create mode 100644 ext/CrashServer/SymUpload.exe create mode 100644 ext/CrashServer/external/MiniZip/MiniZip.vcxproj create mode 100644 ext/CrashServer/external/WTL/CPL.TXT create mode 100644 ext/CrashServer/external/WTL/Include/atlapp.h create mode 100644 ext/CrashServer/external/WTL/Include/atlctrls.h create mode 100644 ext/CrashServer/external/WTL/Include/atlctrlx.h create mode 100644 ext/CrashServer/external/WTL/Include/atlgdi.h create mode 100644 ext/CrashServer/external/WTL/Include/atlres.h create mode 100644 ext/CrashServer/external/WTL/Include/atluser.h create mode 100644 ext/CrashServer/external/WTL/Include/atlwinx.h create mode 100644 ext/CrashServer/external/gsoap-win32-2.8.0/mod_gsoap/gsoap_win/wininet/gsoapWinInet.h create mode 100644 ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.cpp create mode 100644 ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.h create mode 100644 ext/CrashServer/external/zlib123/README create mode 100644 ext/CrashServer/external/zlib123/adler32.c create mode 100644 ext/CrashServer/external/zlib123/compress.c create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/crypt.h create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/ioapi.c create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/ioapi.h create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/iowin32.c create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/iowin32.h create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/mztools.c create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/unzip.c create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/unzip.h create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/zip.c create mode 100644 ext/CrashServer/external/zlib123/contrib/minizip/zip.h create mode 100644 ext/CrashServer/external/zlib123/crc32.c create mode 100644 ext/CrashServer/external/zlib123/crc32.h create mode 100644 ext/CrashServer/external/zlib123/deflate.c create mode 100644 ext/CrashServer/external/zlib123/deflate.h create mode 100644 ext/CrashServer/external/zlib123/gzio.c create mode 100644 ext/CrashServer/external/zlib123/infback.c create mode 100644 ext/CrashServer/external/zlib123/inffast.c create mode 100644 ext/CrashServer/external/zlib123/inffast.h create mode 100644 ext/CrashServer/external/zlib123/inffixed.h create mode 100644 ext/CrashServer/external/zlib123/inflate.c create mode 100644 ext/CrashServer/external/zlib123/inflate.h create mode 100644 ext/CrashServer/external/zlib123/inftrees.c create mode 100644 ext/CrashServer/external/zlib123/inftrees.h create mode 100644 ext/CrashServer/external/zlib123/trees.c create mode 100644 ext/CrashServer/external/zlib123/trees.h create mode 100644 ext/CrashServer/external/zlib123/uncompr.c create mode 100644 ext/CrashServer/external/zlib123/zconf.h create mode 100644 ext/CrashServer/external/zlib123/zlib.h create mode 100644 ext/CrashServer/external/zlib123/zutil.c create mode 100644 ext/CrashServer/external/zlib123/zutil.h diff --git a/ext/CrashServer/CommonLibs/Log/log.cpp b/ext/CrashServer/CommonLibs/Log/log.cpp new file mode 100644 index 000000000..bf340fb9b --- /dev/null +++ b/ext/CrashServer/CommonLibs/Log/log.cpp @@ -0,0 +1,1120 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include "log_media.h" + +#define ASSERT(f) assert(f) + +#ifndef VERIFY +# ifdef _DEBUG +# define VERIFY(f) ASSERT(f) +# else +# define VERIFY(f) ((void)(f)) +# endif +#endif + +static DWORD g_dwThreadNameTlsId = TLS_OUT_OF_INDEXES; +static LPTSTR pszUnknownThreadName = _T("Unknown"); +void InitializeLog() +{ + static bool bInitialized = false; + if (bInitialized) + return; + bInitialized = true; + g_dwThreadNameTlsId = TlsAlloc(); + ASSERT(g_dwThreadNameTlsId != TLS_OUT_OF_INDEXES); +} +LPCTSTR GetLogThreadName() +{ + ASSERT(g_dwThreadNameTlsId != TLS_OUT_OF_INDEXES); + if (g_dwThreadNameTlsId == TLS_OUT_OF_INDEXES) + return NULL; + return static_cast(TlsGetValue(g_dwThreadNameTlsId)); +} +void FreeLogThreadName() +{ + ASSERT(g_dwThreadNameTlsId != TLS_OUT_OF_INDEXES); + if (g_dwThreadNameTlsId == TLS_OUT_OF_INDEXES) + return; + LPTSTR pThreadName = static_cast(TlsGetValue(g_dwThreadNameTlsId)); + if (pThreadName != pszUnknownThreadName) + { + free(pThreadName); + VERIFY(TlsSetValue(g_dwThreadNameTlsId, pszUnknownThreadName)); + } +} +void SetLogThreadName(LPCTSTR pszThreadName) +{ + ASSERT(g_dwThreadNameTlsId != TLS_OUT_OF_INDEXES); + if (g_dwThreadNameTlsId == TLS_OUT_OF_INDEXES) + return; + FreeLogThreadName(); + VERIFY(TlsSetValue(g_dwThreadNameTlsId, LPVOID(pszThreadName != NULL ? _tcsdup(pszThreadName) : pszUnknownThreadName))); +// SetDebuggerThreadName(-1, __LPCSTR(pszThreadName)); +} + +//! Ñîçäà¸ò ïóòü ê ôàéëó. +bool CreateFileDir(LPCTSTR pszFilePath) +{ + // Íàéä¸ì ïîëíûé ïóòü + TCHAR szBuffer[1024]; + LPTSTR pszFilePart; + DWORD dwRes = GetFullPathName(pszFilePath, sizeof(szBuffer)/sizeof(*szBuffer), szBuffer, &pszFilePart); + if (dwRes == 0 + || dwRes >= sizeof(szBuffer)/sizeof(*szBuffer) + || pszFilePart == NULL) + return false; + + // Îòðåæåì èìÿ ôàéëà + *pszFilePart = _T('\0'); + + CString sPath(szBuffer); + sPath.Replace(_T('/'), _T('\\')); + ASSERT(sPath.Right(1) == _T("\\")); + + int nPos; + if (sPath.Left(2) == _T("\\\\")) + nPos = sPath.Find(_T("\\"), sPath.Find(_T("\\"), 2) + 1) + 1; // Ïðîïóñòèì èìÿ êîìïüþòåðà è øàðû + else + nPos = 4; // Ïðîïóñòèì èìÿ äèñêà + while ( (nPos = sPath.Find(_T('\\'), nPos + 1)) != -1) + { + if (!CreateDirectory(sPath.Left(nPos), NULL) && GetLastError() != ERROR_ALREADY_EXISTS) + return false; + } + return true; +} + +void LogBase::SetThreadName(LPCTSTR pszThreadName) +{ + SetLogThreadName(pszThreadName); +} + +LPCTSTR LogBase::GetThreadName() +{ + LPCTSTR pszName = GetLogThreadName(); + return pszName ? pszName : _T("Unknown"); +} + + +LogMediaPtr LogBase::GetAppLogMedia() +{ + static LogMediaPtr pAppLog(new LogMediaProxy()); + return pAppLog; +} + +void LogBase::SetAppLogMedia(LogMediaPtr pLog) +{ + ASSERT(pLog != GetAppLogMedia()); + if (pLog == GetAppLogMedia()) + return; + std::static_pointer_cast(GetAppLogMedia())->SetLog(pLog); +} + +LogMediaPtr LogBase::CreateConsoleMedia() +{ + static LogMediaPtr pConsoleMedia(new ConsoleMedia()); + if (pConsoleMedia->IsWorking()) + return pConsoleMedia; + return LogMediaPtr(); +} + +LogMediaPtr LogBase::CreateFileMedia(LPCTSTR pszFilename, bool bAppend, bool bFlush, bool bNewFileDaily) +{ + LogMediaPtr pLog(new FileMedia(pszFilename, bAppend, bFlush, bNewFileDaily)); + if (pLog->IsWorking()) + return pLog; + return LogMediaPtr(); +} + +LogMediaPtr LogBase::CreateDebugMedia(DWORD dwParam) +{ + LogMediaPtr pDebugMedia(new DebugMedia(dwParam)); + if (pDebugMedia->IsWorking()) + return pDebugMedia; + return LogMediaPtr(); +} + + +////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////// + +void FormatLogMessage(ELogMessageType type, + ELogMessageLevel nLevel, + LPCTSTR pszDate, + LPCTSTR pszTime, + LPCTSTR pszThreadId, + LPCTSTR pszThreadName, + LPCTSTR pszModule, + LPCTSTR pszMessage, + CString& output) +{ +#if 1 + output.Empty(); + output.Preallocate(1024); + + if (type != eLM_DirectOutput) + { + output += pszDate; + output += _T(' '); + output += pszTime; +#if defined(LOG_THREAD_NAME) + output += _T(" ["); + output += pszThreadId; + output += _T(":"); + size_t nThreadNameLen = _tcslen(pszThreadName); + if (nThreadNameLen > 12) + output.append(pszThreadName, 12); + else + { + output.append(12 - nThreadNameLen, _T(' ')); + output += pszThreadName; + } + output += _T("] "); +#else + output += _T(" "); +#endif + + switch (type) + { + case eLM_Info: + output += _T('I'); + break; + case eLM_Debug: + output += _T('-'); + break; + case eLM_Warning: + output += _T('W'); + break; + case eLM_Error: + output += _T('E'); + break; + default: + ASSERT(false); + } + + if (nLevel>0) + output.AppendFormat(_T("%i"), nLevel); + else + output += _T(' '); +#if 0 + output += _T(" : ["); + output += pszModule; + output += _T("] "); +#else + output += _T(" : "); +#endif + } + output += pszMessage; + output.TrimRight(); +#else + output.Empty(); + output.reserve(1024); + + output += pszDate; + output += _T(' '); + output += pszTime; + output += _T("\t"); + output += pszThreadId; + output += _T("\t"); + output += pszThreadName; + output += _T("\t"); + output += pszModule; + output += _T("\t"); + + switch (type) + { + case eLM_Info: + output += _T("Inf"); + break; + case eLM_Debug: + output += _T("Dbg"); + break; + case eLM_Warning: + output += _T("Wrn"); + break; + case eLM_Error: + output += _T("Err"); + break; + default: + ASSERT(false); + } + + if (nLevel>0) + output.AppendFormat(_T("%i"), nLevel); + output += _T('\t'); + output += pszMessage; + output.TrimRight(); +#endif +} + +CString GetSystemInformation() +{ + CString info = _T("Microsoft Windows "); + + OSVERSIONINFOEX rcOS; + ZeroMemory(&rcOS, sizeof(rcOS)); + rcOS.dwOSVersionInfoSize = sizeof(rcOS); + + GetVersionEx((OSVERSIONINFO*)&rcOS); + + if (rcOS.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) + { + switch (rcOS.dwMinorVersion) + { + case 0: info += _T("95"); break; + case 10: info += _T("98"); break; + case 90: info += _T("Me"); break; + } + if (!_tcscmp(rcOS.szCSDVersion, _T(" A"))) + info += _T(" Second Edition"); + else + if (!_tcscmp(rcOS.szCSDVersion, _T(" C"))) + info += _T(" OSR2"); + } + else if (rcOS.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + switch (rcOS.dwMajorVersion) + { + case 3: info += _T("NT 3.51"); break; + case 4: info += _T("NT 4.0"); break; + case 5: + switch (rcOS.dwMinorVersion) + { + case 0: info += _T("2000"); break; + case 1: info += _T("XP"); break; + case 2: info += _T("2003 Server"); break; + default: ASSERT(false); info += _T("future version"); break; + } + break; + case 6: + switch (rcOS.dwMinorVersion) + { + case 0: info += rcOS.wProductType == VER_NT_WORKSTATION ? _T("Vista") : _T("Server 2008"); break; + case 1: info += rcOS.wProductType == VER_NT_WORKSTATION ? _T("7") : _T("Server 2008 R2"); break; + default: ASSERT(false); info += _T("future version"); break; + } + break; + default: ASSERT(false); info += _T("future version"); break; + } + if (_tcslen(rcOS.szCSDVersion) > 0) + { + info += _T(", "); + info += rcOS.szCSDVersion; + } + } + return info; +} + +CString GetModuleInformation() +{ + CString info; + TCHAR szApp[MAX_PATH]; + if(!GetModuleFileName(NULL, szApp, MAX_PATH)) + return info; + + info = szApp; + + DWORD dwDummy; + DWORD dwInfoSize; + + dwInfoSize = GetFileVersionInfoSize(szApp, &dwDummy); + if(dwInfoSize) + { + LPVOID pInfoBuffer = _alloca(dwInfoSize); + if(GetFileVersionInfo(szApp, 0, dwInfoSize, pInfoBuffer)) + { + VS_FIXEDFILEINFO *pInfo = NULL; + UINT InfoSize = 0; + if(VerQueryValue (pInfoBuffer, _T("\\"), (LPVOID *)&pInfo, &InfoSize) && InfoSize == sizeof(VS_FIXEDFILEINFO)) + { + CString strVersion; + strVersion.Format(_T(" (%d.%d.%d.%d)"), + HIWORD(pInfo->dwFileVersionMS), + LOWORD(pInfo->dwFileVersionMS), + HIWORD(pInfo->dwFileVersionLS), + LOWORD(pInfo->dwFileVersionLS) + ); + info += strVersion; + } + } + } + + return info; +} + +////////////////////////////////////////////////////////////////////////// +// CConsoleMedia +////////////////////////////////////////////////////////////////////////// + +ConsoleMedia::ConsoleMedia() +{ + m_bRedirectedToFile = true; + + m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + if (m_hConsole == NULL) + { + if (!AllocConsole() //|| !SetConsoleTitle(_T("Log")) + || (m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE)) == NULL) + return; + } + GetConsoleScreenBufferInfo(m_hConsole, &m_info); + + DWORD t; + m_bRedirectedToFile = GetConsoleMode(m_hConsole, &t) == FALSE; +} + +void ConsoleMedia::Write(ELogMessageType type, + ELogMessageLevel nLevel, + LPCTSTR pszDate, + LPCTSTR pszTime, + LPCTSTR pszThreadId, + LPCTSTR pszThreadName, + LPCTSTR pszModule, + LPCTSTR pszMessage) +{ + if (m_hConsole==NULL) + return; + WORD color = FOREGROUND_GREEN|FOREGROUND_INTENSITY; + //FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_INTENSITY; + switch (type) + { + case eLM_Debug: + color = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; + break; + case eLM_Warning: + color = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY; + break; + case eLM_Error: + color = FOREGROUND_RED|FOREGROUND_INTENSITY; + break; + } + + CString output; + FormatLogMessage(type, nLevel, pszDate, pszTime, pszThreadId, pszThreadName, pszModule, pszMessage, output); + + if (m_bRedirectedToFile) + { + output += _T("\n"); + CStringA outputA = output; + outputA.AnsiToOem(); + + CriticalSection::SyncLock lock(m_cs); + DWORD dwWritten; + WriteFile(m_hConsole, (LPCSTR)outputA, (DWORD)outputA.GetLength(), &dwWritten, NULL); + } + else + { +#ifndef _UNICODE + output.AnsiToOem(); +#endif + CriticalSection::SyncLock lock(m_cs); + SetConsoleTextAttribute(m_hConsole, color); + DWORD dwWritten; + WriteConsole(m_hConsole, (LPCTSTR)output, (DWORD)output.GetLength(), &dwWritten, NULL); + + SetConsoleTextAttribute(m_hConsole, m_info.wAttributes); + WriteConsole(m_hConsole, _T("\n"), 1, &dwWritten, NULL); + } +} + +////////////////////////////////////////////////////////////////////////// +// CFileMedia +////////////////////////////////////////////////////////////////////////// + +FileMedia::FileMedia(LPCTSTR pszFilename, bool bAppend, bool bFlush, bool bNewFileDaily) + : m_bAppend(bAppend), m_bFlush(bFlush), m_bNewFileDaily(bNewFileDaily), m_wLogYear(0), m_wLogMonth(0), m_wLogDay(0), + m_sOrigFilename(pszFilename) +{ + OpenLogFile(); +// SYSTEMTIME st; +// GetLocalTime(&st); +// +// m_sFilename = pszFilename; +// m_sFilename.Replace(_T("%DATETIME%"), _T("%DATE% %TIME%")); +// if (m_sFilename.Find(_T("%DATE%")) != -1) +// { +// TCHAR bufdate[128]; +// _stprintf_s(bufdate, _T("%i-%02i-%02i"), st.wYear, st.wMonth, st.wDay); +// m_sFilename.Replace(_T("%DATE%"), bufdate); +// } +// if (m_sFilename.Find(_T("%TIME%")) != -1) +// { +// GetLocalTime(&st); +// TCHAR buftime[128]; +// _stprintf_s(buftime, _T("%02i-%02i"), st.wHour, st.wMinute); +// m_sFilename.Replace(_T("%TIME%"), buftime); +// } +// +// if (!CreateFileDir(m_sFilename)) +// { +// _RPT1(_CRT_ERROR, "FileMedia: Can't create folder '%S'", (LPCWSTR) m_sFilename); +// return; +// } +// +// +// // Ñîçäàäèì äëÿ äîñòóïà ê ýòîìó ôàéëó ìüþòåêñ +// CString sMtx(m_sFilename); +// sMtx.ToUpper(); +// for (CString::iterator it = sMtx.begin(), end = sMtx.end(); it != end; ++it) +// { +// if (!_istalnum(*it)) +// *it = _T('_'); +// } +// m_hMutex = CreateMutex(NULL, TRUE, (LPCTSTR)sMtx); +// DWORD dwMtxError = GetLastError(); +// +// m_hFile = CreateFile(m_sFilename, +// GENERIC_WRITE, +// FILE_SHARE_READ | FILE_SHARE_WRITE, +// NULL, +// (bAppend || dwMtxError == ERROR_ALREADY_EXISTS) ? OPEN_ALWAYS : CREATE_ALWAYS, +// FILE_ATTRIBUTE_NORMAL, +// NULL); +// +// if (m_hFile == INVALID_HANDLE_VALUE) +// { +// if (dwMtxError != ERROR_ALREADY_EXISTS) +// VERIFY(ReleaseMutex(m_hMutex)); +// m_hMutex.Close(); +// return; +// } +// +// if (dwMtxError != ERROR_ALREADY_EXISTS) +// { +// CString header; +// header.Format( +// _T("================================================\r\n") +// _T("=== Trace Log Started on %i-%02i-%02i %02i:%02i:%02i ===\r\n") +// _T("=== %s ===\r\n") +// _T("================================================\r\n") +// _T("\r\n%s\r\n\r\n") +// , st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond +// , (LPCTSTR)GetSystemInformation() +// , (LPCTSTR)GetModuleInformation()); +// +// LONG dwDistanceToMoveHigh = 0; // Íóæåí, ÷òîáû ïèñàòü â ôàéëû áîëüøå 4Ãá +// VERIFY(SetFilePointer(m_hFile, 0, &dwDistanceToMoveHigh, FILE_END) != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR); +// CStringA headerA = header; +// DWORD dwWritten; +//// VERIFY(WriteFile(m_hFile, (LPCTSTR)header, (DWORD)header.size() * sizeof(TCHAR), &dwWritten, NULL)); +// VERIFY(WriteFile(m_hFile, (LPCSTR)headerA, (DWORD)headerA.size() * sizeof(CHAR), &dwWritten, NULL)); +// if (m_hMutex != NULL) +// VERIFY(ReleaseMutex(m_hMutex)); +// } +} + +FileMedia::~FileMedia() +{ + CloseLogFile(); +// if (m_hFile != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hMutex, 1000) != WAIT_TIMEOUT) +// { +// SYSTEMTIME st; +// GetLocalTime(&st); +// CString header; +// header.Format( +// _T("=================================================\r\n") +// _T("=== Trace Log Finished on %i-%02i-%02i %02i:%02i:%02i ===\r\n") +// _T("=================================================\r\n") +// , st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); +// +// LONG dwDistanceToMoveHigh = 0; // Íóæåí, ÷òîáû ïèñàòü â ôàéëû áîëüøå 4Ãá +// VERIFY(SetFilePointer(m_hFile, 0, &dwDistanceToMoveHigh, FILE_END) != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR); +// CStringA headerA = header; +// DWORD dwWritten; +//// VERIFY(WriteFile(m_hFile, (LPCTSTR)header, (DWORD) header.size() * sizeof(TCHAR), &dwWritten, NULL)); +// VERIFY(WriteFile(m_hFile, (LPCSTR)headerA, (DWORD) headerA.size() * sizeof(CHAR), &dwWritten, NULL)); +// VERIFY(ReleaseMutex(m_hMutex)); +// } +} + +void FileMedia::CloseLogFile() +{ + if (m_hFile != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hMutex, 1000) != WAIT_TIMEOUT) + { + SYSTEMTIME st; + GetLocalTime(&st); + CString header; + header.Format( + _T("=================================================\r\n") + _T("=== Trace Log Finished on %i-%02i-%02i %02i:%02i:%02i ===\r\n") + _T("=================================================\r\n") + , st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + + LONG dwDistanceToMoveHigh = 0; // Íóæåí, ÷òîáû ïèñàòü â ôàéëû áîëüøå 4Ãá + VERIFY(SetFilePointer(m_hFile, 0, &dwDistanceToMoveHigh, FILE_END) != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR); + CStringA headerA = header; + DWORD dwWritten; +// VERIFY(WriteFile(m_hFile, (LPCTSTR)header, (DWORD) header.size() * sizeof(TCHAR), &dwWritten, NULL)); + VERIFY(WriteFile(m_hFile, (LPCSTR)headerA, (DWORD) headerA.GetLength() * sizeof(CHAR), &dwWritten, NULL)); + VERIFY(ReleaseMutex(m_hMutex)); + } +} + +bool FileMedia::IsWorking() const +{ + return m_hFile != INVALID_HANDLE_VALUE; +} + +void FileMedia::OpenLogFile() +{ + SYSTEMTIME st; + GetLocalTime(&st); + + m_sFilename = m_sOrigFilename; + m_sFilename.Replace(_T("%DATETIME%"), _T("%DATE% %TIME%")); + if (m_sFilename.Find(_T("%DATE%")) != -1) + { + TCHAR bufdate[128]; + _stprintf_s(bufdate, _T("%i-%02i-%02i"), st.wYear, st.wMonth, st.wDay); + m_sFilename.Replace(_T("%DATE%"), bufdate); + m_wLogYear = st.wYear; + m_wLogMonth = st.wMonth; + m_wLogDay = st.wDay; + } + if (m_sFilename.Find(_T("%TIME%")) != -1) + { + GetLocalTime(&st); + TCHAR buftime[128]; + _stprintf_s(buftime, _T("%02i-%02i"), st.wHour, st.wMinute); + m_sFilename.Replace(_T("%TIME%"), buftime); + } + + if (!CreateFileDir(m_sFilename)) + { + _RPT1(_CRT_ERROR, "FileMedia: Can't create folder '%S'", (LPCWSTR) CStringW(m_sFilename)); + return; + } + + + // Ñîçäàäèì äëÿ äîñòóïà ê ýòîìó ôàéëó ìüþòåêñ + CString sMtx(m_sFilename); + sMtx.MakeUpper(); + for (int i = 0, size = sMtx.GetLength(); i < size; ++i) + { + if (!_istalnum(sMtx[i])) + sMtx.SetAt(i, _T('_')); + } + m_hMutex = CreateMutex(NULL, TRUE, (LPCTSTR)sMtx); + DWORD dwMtxError = GetLastError(); + + m_hFile = CreateFile(m_sFilename, + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + (m_bAppend || dwMtxError == ERROR_ALREADY_EXISTS) ? OPEN_ALWAYS : CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (m_hFile == INVALID_HANDLE_VALUE) + { + if (dwMtxError != ERROR_ALREADY_EXISTS) + VERIFY(ReleaseMutex(m_hMutex)); + m_hMutex.Close(); + return; + } + + if (dwMtxError != ERROR_ALREADY_EXISTS) + { + CString header; + header.Format( + _T("================================================\r\n") + _T("=== Trace Log Started on %i-%02i-%02i %02i:%02i:%02i ===\r\n") + _T("=== %s ===\r\n") + _T("================================================\r\n") + _T("\r\n%s\r\n\r\n") + , st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond + , (LPCTSTR)GetSystemInformation() + , (LPCTSTR)GetModuleInformation()); + + LONG dwDistanceToMoveHigh = 0; // Íóæåí, ÷òîáû ïèñàòü â ôàéëû áîëüøå 4Ãá + VERIFY(SetFilePointer(m_hFile, 0, &dwDistanceToMoveHigh, FILE_END) != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR); + CStringA headerA = header; + DWORD dwWritten; +// VERIFY(WriteFile(m_hFile, (LPCTSTR)header, (DWORD)header.size() * sizeof(TCHAR), &dwWritten, NULL)); + VERIFY(WriteFile(m_hFile, (LPCSTR)headerA, (DWORD)headerA.GetLength() * sizeof(CHAR), &dwWritten, NULL)); + if (m_hMutex != NULL) + VERIFY(ReleaseMutex(m_hMutex)); + } +} + +void FileMedia::Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage) +{ + if (m_bNewFileDaily && m_wLogYear != 0) + { + SYSTEMTIME st; + GetLocalTime(&st); + if (st.wDay != m_wLogDay || st.wMonth != m_wLogMonth || st.wDay != m_wLogDay) + { + CloseLogFile(); + OpenLogFile(); + } + } + + if (WaitForSingleObject(m_hMutex, 1000) == WAIT_TIMEOUT) + return; + + // trying to restore access + if (m_hFile == INVALID_HANDLE_VALUE) + { + m_hFile = CreateFile(m_sFilename, + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (m_hFile == INVALID_HANDLE_VALUE) + { + VERIFY(ReleaseMutex(m_hMutex)); + return; + } + } + + LONG dwDistanceToMoveHigh = 0; // Íóæåí, ÷òîáû ïèñàòü â ôàéëû áîëüøå 4Ãá + if (SetFilePointer(m_hFile, 0, &dwDistanceToMoveHigh, FILE_END) == INVALID_SET_FILE_POINTER + && GetLastError() != NO_ERROR) + { + _RPT0(_CRT_ERROR, "FileMedia: Can't set file pointer"); + m_hFile.Close(); + VERIFY(ReleaseMutex(m_hMutex)); + return; + } + + CString output; + FormatLogMessage(type, nLevel, pszDate, pszTime, pszThreadId, pszThreadName, pszModule, pszMessage, output); + output += _T("\r\n"); + + CStringA outputA = output; + + DWORD dwWritten; +// VERIFY(WriteFile(m_hFile, (LPCTSTR)output, (DWORD) output.size() * sizeof(TCHAR), &dwWritten, NULL)); + VERIFY(WriteFile(m_hFile, (LPCSTR)outputA, (DWORD) outputA.GetLength() * sizeof(CHAR), &dwWritten, NULL)); + if (m_bFlush) + VERIFY(FlushFileBuffers(m_hFile)); + VERIFY(ReleaseMutex(m_hMutex)); +} + +////////////////////////////////////////////////////////////////////////// +// CDebugMedia +////////////////////////////////////////////////////////////////////////// + +DebugMedia::DebugMedia(DWORD dwParam) + : m_dwParam(dwParam) +{ +} + +extern "C" WINBASEAPI BOOL WINAPI IsDebuggerPresent ( VOID ); + +bool DebugMedia::IsWorking() const +{ + return (m_dwParam & LogBase::DEBUGMEDIA_FORCE) ? true : IsDebuggerPresent() != FALSE; +} + +void DebugMedia::Write(ELogMessageType type, + ELogMessageLevel nLevel, + LPCTSTR pszDate, + LPCTSTR pszTime, + LPCTSTR pszThreadId, + LPCTSTR pszThreadName, + LPCTSTR pszModule, + LPCTSTR pszMessage) +{ + CString output; + FormatLogMessage(type, nLevel, pszDate, pszTime, pszThreadId, pszThreadName, pszModule, pszMessage, output); + output += _T('\n'); + + OutputDebugString(output); + if (type == eLM_Error && (m_dwParam & LogBase::DEBUGMEDIA_REPORTERRORS)) + { + _RPT1(_CRT_ERROR, "%ws", static_cast(output)); + } +} + +////////////////////////////////////////////////////////////////////////// +// LogMediaProxy +////////////////////////////////////////////////////////////////////////// + +LogMediaProxy::LogMediaProxy(const LogMediaPtr& pLog) + : m_pLog(pLog) +{ +} + +LogMediaProxy::~LogMediaProxy() +{ +} + +void LogMediaProxy::SetLog(const LogMediaPtr& pLog) +{ + CriticalSection::SyncLock lock(m_cs); + m_pLog = pLog; +} + +void LogMediaProxy::Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage) +{ + CriticalSection::SyncLock lock(m_cs); + if (m_pLog) + m_pLog->Write(type, nLevel, pszDate, pszTime, pszThreadId, pszThreadName, pszModule, pszMessage); +} + +bool LogMediaProxy::Check(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszModule) +{ + CriticalSection::SyncLock lock(m_cs); + if (m_pLog) + return m_pLog->Check(type, nLevel, pszModule); + return false; +} + +////////////////////////////////////////////////////////////////////////// +// LogMediaColl +////////////////////////////////////////////////////////////////////////// + +LogMediaColl::LogMediaColl() +{ +} + +LogMediaColl::~LogMediaColl() +{ +} + +void LogMediaColl::Add(const LogMediaPtr& pMedia) +{ + if (!pMedia) + return; + CriticalSection::SyncLock lock(m_cs); + m_MediaColl.push_back(pMedia); +} + +void LogMediaColl::Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage) +{ + CriticalSection::SyncLock lock(m_cs); + for (MediaColl::iterator it = m_MediaColl.begin(), end = m_MediaColl.end(); it != end; ++it) + (*it)->Write(type, nLevel, pszDate, pszTime, pszThreadId, pszThreadName, pszModule, pszMessage); +} + +bool LogMediaColl::Check(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszModule) +{ + CriticalSection::SyncLock lock(m_cs); + // Åñëè õîòÿ áû îäèí ëîã ïðîïóñêàåò, òî è ìû ïðîïóñêàåì. + for (MediaColl::iterator it = m_MediaColl.begin(), end = m_MediaColl.end(); it != end; ++it) + if ((*it)->Check(type, nLevel, pszModule)) + return true; + return false; +}; + +////////////////////////////////////////////////////////////////////////// +// CFilterLogMedia +////////////////////////////////////////////////////////////////////////// + +FilterLogMedia::FilterLogMedia(const LogMediaPtr& pMedia) + : m_pMedia(pMedia) +{ +} + +FilterLogMedia::~FilterLogMedia() +{ +} + +void FilterLogMedia::AddFilter(FilterPtr pFilter) +{ + CriticalSection::SyncLock lock(m_cs); + m_FilterColl.push_back(pFilter); +} + +void FilterLogMedia::Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage) +{ + if (!m_pMedia) + return; + { + CriticalSection::SyncLock lock(m_cs); + for (FilterColl::iterator it = m_FilterColl.begin(), end = m_FilterColl.end(); it != end; ++it) + if (!(*it)->Check(type, nLevel, pszModule)) + return; + } + m_pMedia->Write(type, nLevel, pszDate, pszTime, pszThreadId, pszThreadName, pszModule, pszMessage); +} + +bool FilterLogMedia::Check(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszModule) +{ + if (!m_pMedia) + return false; + { + CriticalSection::SyncLock lock(m_cs); + for (FilterColl::iterator it = m_FilterColl.begin(), end = m_FilterColl.end(); it != end; ++it) + if (!(*it)->Check(type, nLevel, pszModule)) + return false; + } + return m_pMedia->Check(type, nLevel, pszModule); +} + +////////////////////////////////////////////////////////////////////////// +// LogBase +////////////////////////////////////////////////////////////////////////// + +LogBase::LogBase(LogMediaPtr pMedia, LPCTSTR pszModule) + : m_szModule(pszModule) + , m_pMedia(pMedia) +{ + ASSERT(pszModule != NULL); +} + +LogBase::~LogBase() +{ +} + +template +class StackResizableBuf +{ + T loc_data[nSize]; + void Clear() { if (data != loc_data) delete[] data; } +public: + StackResizableBuf() { data = loc_data; size = nSize; } + ~StackResizableBuf() { Clear(); } + void Resize(size_t nNewSize) { Clear(); data = new T[nNewSize]; size = nNewSize; } + + T* data; + size_t size; +}; + +bool LogBase::IsFiltered(ELogMessageType type, ELogMessageLevel nLevel) +{ + return !m_pMedia || !m_pMedia->Check(type, nLevel, m_szModule.c_str()); +} + +void LogBase::WriteVA(ELogMessageType type, + ELogMessageLevel nLevel, + LPCTSTR pszModule, + LPCTSTR pszMessage, + va_list args) throw() +{ + if (IsFiltered(type, nLevel)) // íå îáðàáàòûâàåì ñîîáùåíèå, åñëè îíî íå ïîïàäàåò â ëîã + return; + // 75% âðåìåíè òðàòèòñÿ íà new è delete, ïîýòîìó ïåðâóþ ïîïûòêó ïîïðîáóåì ñäåëàòü áåç íåãî. + StackResizableBuf buf; + int pos; + for (;;) + { + pos = _vsntprintf_s(buf.data, buf.size, buf.size - 1, pszMessage, args); + if (pos != -1) + break; + // BUG 16456 FIX, ñì. â êîíåö WriteVAW ïî÷åìó + //if (buf.size >= 1024 * 256) + if (buf.size >= 1024 * 1024 * 10) //Increased limit for DumpServer + { + pos = (int)buf.size - 1; + break; + } + buf.Resize(buf.size * 2); + } + if (pos >= 0) + { + buf.data[pos] = 0; + SYSTEMTIME st; + GetLocalTime(&st); + TCHAR bufdate[128], buftime[128], bufthread[128]; + _stprintf_s(bufdate, _T("%i-%02i-%02i"), st.wYear, st.wMonth, st.wDay); + _stprintf_s(buftime, _T("%02i:%02i:%02i.%03d"), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + _stprintf_s(bufthread, _T("%4x"), GetCurrentThreadId()); + m_pMedia->Write(type, nLevel, bufdate, buftime, bufthread, GetThreadName() + , pszModule ? pszModule : m_szModule.c_str(), buf.data); + } +} + +void LogBase::WriteVAW(ELogMessageType type, + ELogMessageLevel nLevel, + LPCWSTR pszModule, + LPCWSTR pszMessage, + va_list args) throw() +{ +#if defined(_UNICODE) || defined(UNICODE) + WriteVA(type, nLevel, pszModule, pszMessage, args); +#else + + if (IsFiltered(type, nLevel)) // íå îáðàáàòûâàåì ñîîáùåíèå, åñëè îíî íå ïîïàäàåò â ëîã + return; + // 75% âðåìåíè òðàòèòñÿ íà new è delete, ïîýòîìó ïåðâóþ ïîïûòêó ïîïðîáóåì ñäåëàòü áåç íåãî. + StackResizableBuf buf; + int pos; + for (;;) + { + pos = _vsnwprintf(buf.data, buf.size - 1, pszMessage, args); + if (pos != -1) + break; + // BUG 16456 FIX, ñì. â êîíåö WriteVAW ïî÷åìó + if (buf.size >= 1024 * 256) + { + pos = buf.size - 1; + break; + } + buf.Resize(buf.size * 2); + } + if (pos >= 0) + { + buf.data[pos] = 0; + LPTSTR pszStr = static_cast(_alloca(buf.size)); + if (0 == WideCharToMultiByte(CP_ACP, 0/*WC_DEFAULTCHAR*/, buf.data, pos + 1, pszStr, buf.size, NULL, NULL)) + { + _RPT1(_CRT_ERROR, "Can't convert Unicode string (error #0x%08X)", GetLastError()); + return; + } + + LPCTSTR pszMod; + if (pszModule == NULL) + pszMod = m_szModule.c_str(); + else + { + size_t nModuleLen = wcslen(pszModule) + 1; + LPTSTR pszModBuf = static_cast(_alloca(nModuleLen)); + if (0 == WideCharToMultiByte(CP_ACP, 0/*WC_DEFAULTCHAR*/, pszModule, nModuleLen, pszModBuf, nModuleLen, NULL, NULL)) + { + _RPT1(_CRT_ERROR, "Can't convert Unicode string (error #0x%08X)", GetLastError()); + return; + } + pszMod = pszModBuf; + } + + SYSTEMTIME st; + GetLocalTime(&st); + TCHAR bufdate[128], buftime[128], bufthread[128]; + _stprintf(bufdate, _T("%i-%02i-%02i"), st.wYear, st.wMonth, st.wDay); + _stprintf(buftime, _T("%02i:%02i:%02i.%03d"), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + _stprintf(bufthread, _T("%03x"), GetCurrentThreadId()); + m_pMedia->Write(type, nLevel, bufdate, buftime, bufthread, GetThreadName(), pszMod, pszStr); + } +#endif + /* BUG 16456 FIX + _vsnwprintf ñïîòûêàåòñÿ íà ñòðîêàõ ñ ñèìâîëîì 0xFFFF, + âîçâðàùàåò -1 ïðè ëþáîé äëèíå áóôåðà. Ñîîòâåòñâòâåííî + áóôåð óâåëè÷èâàåòñÿ (Resize) ïîêà íå õâàòèò ïàìÿòè, + à ïîòîì âûçûâàåòñÿ _vsnwprintf íà NULL. + Ðåøåíèå: Ò.ê. _vsnwprintf, äàæå åñëè íåõâàòàåò áóôåðà, íà÷àëî çàïîëíÿåò, + òî ïðîñòî îãðàíè÷èì áóôåð 256êá (à 0 íà êîíöå è òàê ñòàâèì íà âñÿêèé ñëó÷àé) + + #include + #include + + void WriteVAW(wchar_t* pszMessage, va_list args) + { + wchar_t buf[1000]; + int n = _vsnwprintf(buf, 1000, pszMessage, args); + printf("Return %i\nBuf is: \"%ls\"", n, buf); // n áóäåò -1, õîòÿ áóôåðà õâàòàåò !!! + } + void WriteW(wchar_t* pszMessage, ...) + { + va_list ap; + va_start(ap, pszMessage); + WriteVAW(pszMessage, ap); + va_end(ap); + } + void main() + { + WriteW(L"%ls!", L"123\xffff"); + } + */ +} + + +////////////////////////////////////////////////////////////////////////// +// CLocalLog +////////////////////////////////////////////////////////////////////////// + +LocalLog::LocalLog(const LogParam& param, LPCTSTR pszModule) + : LogBase(param.m_pMedia, param.m_pszModule ? param.m_pszModule : pszModule) +{ +} + +LocalLog::LocalLog(LogMediaPtr pMedia, LPCTSTR pszModule) + : LogBase(pMedia, pszModule) +{ + ASSERT(pszModule != NULL); +} + +LocalLog::LocalLog(const LogBase& log, LPCTSTR pszModule) + : LogBase(log.GetMedia(), pszModule) +{ +} + +LocalLog::~LocalLog() +{ +} + +////////////////////////////////////////////////////////////////////////// +// Log +////////////////////////////////////////////////////////////////////////// + +Log::Log(const LogParam& param, LPCTSTR pszModule) + : LogBase(param.m_pMedia, param.m_pszModule ? param.m_pszModule : pszModule) +{ +} + +Log::Log(LogMediaPtr pMedia, LPCTSTR pszModule) + : LogBase(pMedia, pszModule) +{ +} + +Log::Log(const LogBase& log, LPCTSTR pszModule) + : LogBase(log.GetMedia(), pszModule) +{ +} + +Log::~Log() +{ +} + +void Log::SetParams(LogMediaPtr pMedia, LPCTSTR pszModule) +{ + CriticalSection::SyncLock lock(m_cs); + m_pMedia = pMedia; + if (pszModule != NULL) + m_szModule = pszModule; +} + +void Log::WriteVA(ELogMessageType type, + ELogMessageLevel nLevel, + LPCTSTR pszModule, + LPCTSTR pszMessage, + va_list args) throw() +{ + CriticalSection::SyncLock lock(m_cs); + LogBase::WriteVA(type, nLevel, pszModule, pszMessage, args); +} + +void Log::WriteVAW(ELogMessageType type, + ELogMessageLevel nLevel, + LPCWSTR pszModule, + LPCWSTR pszMessage, + va_list args) throw() +{ + CriticalSection::SyncLock lock(m_cs); + LogBase::WriteVAW(type, nLevel, pszModule, pszMessage, args); +} + +////////////////////////////////////////////////////////////////////////// +// CFilterLog +////////////////////////////////////////////////////////////////////////// + +FilterLog::~FilterLog() +{ +} diff --git a/ext/CrashServer/CommonLibs/Log/log.h b/ext/CrashServer/CommonLibs/Log/log.h new file mode 100644 index 000000000..d51631162 --- /dev/null +++ b/ext/CrashServer/CommonLibs/Log/log.h @@ -0,0 +1,418 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __LOG_H +#define __LOG_H + +#include +#include +#include +#include +#include +#include "synchro.h" +#include + +#pragma warning (disable: 4251) // need dll-linkage + +void InitializeLog(); +void FreeLogThreadName(); +void SetLogThreadName(LPCTSTR pszThreadName); + +//! Òèïû ñîîáùåíèé. +enum ELogMessageType +{ + eLM_Error, //!< "Îøèáêà" - ïðîèçîø¸ë ñáîé â ðàáîòå, äàëüíåéøåå âûïîëíåíèå òåêóùåãî äåéñòâèÿ íåâîçìîæíî. + eLM_Warning, //!< "Ïðåäóïðåæäåíèå" - ïðîèçîø¸ë ñáîé â ðàáîòå, êîòîðûé óäàëîñü èñïðàâèòü. + eLM_Info, //!< "Èíôîðìàöèÿ" - ñîîáùåíèå î âûïîëíåíèè íåêîòîðîãî äåéñòâèÿ ïðîãðàììîé. + eLM_Debug, //!< "Îòëàäêà" - ñîîáùåíèå, ñîäåðæàùåå îòëàäî÷íóþ èíôîðìàöèþ. + eLM_DirectOutput //!< Ïåðåíàïðàâëåíèå â ëîã âûâîäà âíåøíåãî êîíñîëüíîãî ïðèëîæåíèÿ +}; + +//! Óðîâåíü âàæíîñòè ñîîáùåíèé. +enum ELogMessageLevel +{ + L0 = 0, //!< Íàèáîëåå âàæíûé. + L1 = 1, + L2 = 2, + L3 = 3, + L4 = 4, + L5 = 5, + LMAX = 255 +}; + +//! Èíòåðôåéñ "ôèçè÷åñêîãî" ëîãà. Îñóùåñòâëÿåò çàïèñü íà íîñèòåëü. +class ILogMedia +{ +public: + virtual ~ILogMedia() {} + //! Çàïèñûâàåò ñîîáùåíèå. + virtual void Write( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCTSTR pszDate, //!< [in] Äàòà çàïèñè ñîîáùåíèÿ. + LPCTSTR pszTime, //!< [in] Âðåìÿ çàïèñè ñîîáùåíèÿ. + LPCTSTR pszThreadId, //!< [in] Èäåíòèôèêàòîð ïîòîêà, èç êîòîðîãî çàïèñàíî ñîîáùåíèå. + LPCTSTR pszThreadName, //!< [in] Èìÿ ïîòîêà, èç êîòîðîãî çàïèñàíî ñîîáùåíèå. + LPCTSTR pszModule, //!< [in] Ìîäóëü, èç êîòîðîãî çàïèñàíî ñîîáùåíèå. + LPCTSTR pszMessage //!< [in] Ñîîáùåíèå. + ) = 0; + //! Ðàçðåøàåò, èñêëþ÷àåò èëè ìîäèôèöèðóåò ñîîáùåíèå. + //! \return false - Ñîîáùåíèå èãíîðèðóåòñÿ. + virtual bool Check( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCTSTR pszModule //!< [in] Ìîäóëü, èç êîòîðîãî çàïèñàíî ñîîáùåíèÿ. + ) + { + type; nLevel; pszModule; + return true; + }; + //! Âîçâðàùàåò, ðàáîòàåò ëè ëîã. + //! Åñëè ëîã áûë íåóäà÷íî ñîçäàí (íàïðèìåð, êðèâîå èìÿ ôàéëà), óçíàòü îá ýòîì ìîæíî çäåñü. + virtual bool IsWorking() const { return true; } +}; + +typedef std::shared_ptr LogMediaPtr; + +//! Ëîã-çàãëóøêà. +class LogMediaProxy: public ILogMedia +{ +public: + LogMediaProxy(const LogMediaPtr& pLog = LogMediaPtr()); + ~LogMediaProxy(); + void SetLog(const LogMediaPtr& pLog); + virtual void Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage); + virtual bool Check(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszModule); +private: + LogMediaPtr m_pLog; + CriticalSection m_cs; +}; + +//! Êîìïîíîâùèê "ôèçè÷åñêèõ" ëîãîâ. +class LogMediaColl: public ILogMedia +{ + typedef std::vector MediaColl; +public: + LogMediaColl(); + ~LogMediaColl(); + void Add(const LogMediaPtr& pMedia); + virtual void Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage); + virtual bool Check(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszModule); +private: + MediaColl m_MediaColl; + CriticalSection m_cs; +}; + +//! Èíòåðôåéñ ôèëüòðàöèè ñîîáùåíèé ëîãà. +class IFilter +{ +public: + virtual ~IFilter() {} + //! Ðàçðåøàåò, èñêëþ÷àåò èëè ìîäèôèöèðóåò ñîîáùåíèå. + //! \return false - Ñîîáùåíèå èãíîðèðóåòñÿ. + virtual bool Check( + ELogMessageType& type, //!< [in/out] Òèï ñîîáùåíèÿ. + ELogMessageLevel& nLevel, //!< [in/out] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCTSTR pszModule //!< [in] Ìîäóëü, èç êîòîðîãî çàïèñàíî ñîîáùåíèÿ. + ) = 0; +}; + +typedef std::shared_ptr FilterPtr; + +//! Ôèëüòð ïî òèïó è óðîâíþ ñîîáùåíèÿ. +//! Ðàçðåøàåò ñîîáùåíèÿ áîëåå ïðèîðèòåòíîãî òèïà è ñîîáùåíèÿ óêàçàííîãî òèïà ñ âàæíîñòüþ íå íèæå óêàçàííîé. +class TypeLevelFilter: public IFilter +{ + ELogMessageType m_type; + ELogMessageLevel m_nLevel; +public: + //! Êîíñòðóêòîð. + TypeLevelFilter( + ELogMessageType type = eLM_Info, //!< [in] Ðàçðåøàåò ñîîáùåíèÿ ïðèîðèòåòíee type. + ELogMessageLevel nLevel = LMAX //!< [in] Ðàçðåøàåò òèïà type ñ âàæíîñòüþ íå íèæå nLevel. + ): m_type(type), m_nLevel(nLevel) {} + virtual bool Check(ELogMessageType& type, ELogMessageLevel& nLevel, LPCTSTR) + { + return type < m_type || (type == m_type && nLevel <= m_nLevel); + } +}; + +//! Ôèëüòðóþùèé ëîã. +class FilterLogMedia: public ILogMedia +{ + typedef std::vector FilterColl; +public: + //! Êîíñòðóêòîð. + FilterLogMedia( + const LogMediaPtr& pMedia //!< [in] Ëîã, íà êîòîðûé íàêëàäûâàåòñÿ ôèëüòð. + ); + virtual ~FilterLogMedia(); + //! Äîáàâëÿåò ôèëüòð. + void AddFilter( + FilterPtr pFilter //!< [in] Ôèëüòð. + ); + virtual void Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage); + virtual bool Check(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszModule); + +private: + LogMediaPtr m_pMedia; + FilterColl m_FilterColl; + CriticalSection m_cs; +}; + +//! Ïàðàìåòðû ñîçäàíèÿ ëîãà. +struct LogParam +{ + LogParam( + LogMediaPtr pMedia = LogMediaPtr(), //!< [in] + LPCTSTR pszModule = NULL //!< [in] + ): m_pMedia(pMedia), m_pszModule(pszModule) {} + LogMediaPtr m_pMedia; + LPCTSTR m_pszModule; +}; + +//! "Ëîãè÷åñêèé" ëîã. +class LogBase +{ +public: + virtual ~LogBase(); + //! Âîçâðàøàåò "ôèçè÷åñêèé" ëîã äàííîãî ëîãà. + LogMediaPtr GetMedia() const throw() { return m_pMedia; } + + //! Çàïèñûâàåò ôîðìàòèðîâàííîå ñîîáùåíèå. + void Write( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCTSTR pszMessage, //!< [in] Ñîîáùåíèå. + ... + ) throw() + { + va_list ap; + va_start(ap, pszMessage); + WriteVA(type, nLevel, NULL, pszMessage, ap); + va_end(ap); + } + + //! Çàïèñûâàåò ôîðìàòèðîâàííîå Unicode-ñîîáùåíèå. + void WriteW( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCWSTR pszModule, //!< [in] Èìÿ ìîäóëÿ. (NULL - èìÿ ïî óìîë÷àíèþ) + LPCWSTR pszMessage, //!< [in] Ñîîáùåíèå. + ... + ) throw() + { + va_list ap; + va_start(ap, pszMessage); + WriteVAW(type, nLevel, pszModule, pszMessage, ap); + va_end(ap); + } + + //! Çàïèñûâàåò ôîðìàòèðîâàííîå ñîîáùåíèå. + virtual void WriteVA( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCTSTR pszModule, //!< [in] Èìÿ ìîäóëÿ. (NULL - èìÿ ïî óìîë÷àíèþ) + LPCTSTR pszMessage, //!< [in] Ñîîáùåíèå. + va_list args + ) throw(); + + //! Çàïèñûâàåò ôîðìàòèðîâàííîå Unicode-ñîîáùåíèå. + virtual void WriteVAW( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCWSTR pszModule, //!< [in] Èìÿ ìîäóëÿ. (NULL - èìÿ ïî óìîë÷àíèþ) + LPCWSTR pszMessage, //!< [in] Ñîîáùåíèå. + va_list args + ) throw(); + + void Debug(LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Debug, L0, NULL, pszMessage, ap); va_end(ap); } + void Debug(ELogMessageLevel nLevel, LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Debug, nLevel, NULL, pszMessage, ap); va_end(ap); } + + void Info(LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Info, L0, NULL, pszMessage, ap); va_end(ap); } + void Info(ELogMessageLevel nLevel, LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Info, nLevel, NULL, pszMessage, ap); va_end(ap); } + + void Warning(LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Warning, L0, NULL, pszMessage, ap); va_end(ap); } + void Warning(ELogMessageLevel nLevel, LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Warning, nLevel, NULL, pszMessage, ap); va_end(ap); } + + void Error(LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Error, L0, NULL, pszMessage, ap); va_end(ap); } + void Error(ELogMessageLevel nLevel, LPCTSTR pszMessage, ...) throw() { va_list ap; va_start(ap, pszMessage); WriteVA(eLM_Error, nLevel, NULL, pszMessage, ap); va_end(ap); } + + //! Ïðîâåðÿåò, ïîïàä¸ò ëè ýòî ñîîáùåíèå â ëîã. + bool IsFiltered(ELogMessageType type, ELogMessageLevel nLevel); + + //! Óñòàíàâëèâàåò íàçâàíèå ïîòîêà. + static void SetThreadName( + LPCTSTR pszThreadName //!< [in] Èìÿ ïîòîêà. Óêàçàòåëü äîëæåí áûòü âàëèäíûì â òå÷åíèè ðàáîòû ïîòîêà. + ); + + //! Âîçðàùàåò óñòàíàâëåííîå íàçâàíèå ïîòîêà. + static LPCTSTR GetThreadName(); + + //! Âîçâðàùàåò "ôèçè÷åñêèé" ëîã ïðèëîæåíèÿ. (Ïðåäñòàâëÿåò ñîáîé LogMediaProxy) + static LogMediaPtr GetAppLogMedia(); + + //! Óñòàíàâëèâàåò "ôèçè÷åñêèé" ëîã ïðèëîæåíèÿ. + static void SetAppLogMedia(LogMediaPtr pLog); + + static LogMediaPtr CreateConsoleMedia(); + + static LogMediaPtr CreateFileMedia( + LPCTSTR pszFilename, //!< [in] Èìÿ ôàéëà. + bool bAppend, //!< [in] Ôëàã äîáàâëåíèÿ â êîíåö. + bool bFlush = false, //!< [in] Ôëàã ñáðîñà íà äèñê ïîñëå êàæäîãî Write. + bool bNewFileDaily = false + ); + + enum EDebugMediaStartParams + { + DEBUGMEDIA_NORMAL = 0x1, + DEBUGMEDIA_FORCE = 0x2, //!< Ñîçäàòü äàæå åñëè íåò îòëàä÷èêà. + DEBUGMEDIA_REPORTERRORS = 0x4, //!< Âûâîäèòü îøèáêè ÷åðåç _CrtDbgReport. + }; + static LogMediaPtr CreateDebugMedia( + DWORD dwParam = DEBUGMEDIA_NORMAL //!< [in] Ñîçäàòü äàæå åñëè íåò îòëàä÷èêà. + ); + + /*! Ñîçäà¸ò ëîã èç îïèñàíèÿ â ðååñòðå. +  óêàçàííîì êëþ÷å ìîãóò íàõîäèòñÿ ñëåäóþùèå ïåðåìåííûå: + REG_SZ "TraceHeader" - Ïåðâîé ñòðîêîé â ëîã áóäåò äîáàâëåí ýòîò òåêñò + REG_SZ "TraceFile" - ëîã áóäåò ïîäêëþ÷åí ê ôàéëó, óêàçàííîìó â çíà÷åíèè ïåðåìåííîé + REG_DWORD "TraceFileAppend" (def: 1) - ôëàã äîïèñûâàòü â êîíåö ôàéëà + REG_DWORD "TraceFileFlush" (def: 0) - ôëàã ñáðîñà íà äèñê ïîñëå êàæäîé çàïèñè + REG_DWORD "TraceToApp" = 1 - ëîã áóäåò ïîäêëþ÷åí ê ëîãó ïðèëîæåíèÿ. + REG_DWORD "TraceToConsole" = 1 - ëîã áóäåò ïîäêëþ÷åí ê îêíó êîíñîëè + REG_DWORD "TraceToDebug" = 1 - ëîã áóäåò ïîäêëþ÷åí ê ëîãó îòëàä÷èêà (Debug Output). + Íà âñå ýòè ëîãè ìîæíî íàëîæèòü ôèëüòð. + Âîçìîæíû ñëåäóþùèå ôèëüòðû: + REG_SZ "TraceType" = ["debug"|"info"|"warning"|"error"] - òèï, ñîîáùåíèÿ íèæå êîòîðîãî îòîáðàæàòüñÿ íå áóäóò. + REG_DWORD "TraceLevel" = [0|1|2|...] - óðîâåíü òèïà TraceType, ñîîáùåíèÿ íèæå êîòîðîãî îòîáðàæàòüñÿ íå áóäóò. + Åñëè íåîáõîäèìî íàêëàäûâàòü ôèëüòðû èíäèâèäóàëüíî äëÿ êàæäîãî ëîãà, èëè íåîáõîäèìî + íåñêîëüêî ëîãîâ îäíîãî òèïà (íàïðèìåð, ïèñàòü â äâà ôàéëà), òî â óêàçàííîì êëþ÷å + ìîæíî çàâåñòè ïîäêëþ÷è "Trace1" "Trace2" è ò.ä. (äîëæíû èäòè ïîñëåäîâàòåëüíî íà÷èíàÿ ñ 1) + â êîòîðûõ ìîæíî óêàçàòü äîïîëíèòåëüíûå ëîãè è ôèëüòðû. + Ôèëüòðû â êëþ÷å âëèÿþò è íà ïîäêëþ÷è òîæå! + Ïðèìåð: + HLKM\....\SomeComp + REG_SZ "TraceFile" = "c:\my.log" + HLKM\....\SomeComp\Trace1 + REG_DWORD "TraceToDebug" = 1 + REG_SZ "TraceType" = "warning" + REG_DWORD "TraceLevel" = 5 + Îçíà÷àåò: ïèñàòü â ôàéë âñ¸, â äåáàã âñå îøèáêè è ïðåäóïðåæäåíèÿ óðîâíÿ 5 è íèæå. + + + \return Ëîã, êîòîðûé ìîæíî ïåðåäàòü â Log. + */ + static LogMediaPtr CreateMediaFromRegistry( + HKEY hRoot, //!< [in] Êîðíåâîé ýëåìåíò ðååñòðà. + LPCTSTR pszPath, //!< [in] Ïóòü îò êîðíåâîãî ýëåìåíòà, äî ðàçäåëà, ñîäåðæàùåãî îïèñàíèå ëîãà. + bool bAppLog = false //!< [in] Äëÿ ëîãà ïðèëîæåíèÿ äîëæåí áûòü true. Òàêæå óñòàíàâëèâàåò ëîã ïðèëîæåíèÿ (SetAppLogMedia()). + ); + +protected: + //! Êîíñòðóêòîð. + LogBase( + LogMediaPtr pMedia, //!< [in] Ëîã. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ. + ); + LogMediaPtr m_pMedia; + std::basic_string m_szModule; +}; + +class LocalLog: public LogBase +{ +public: + //! Êîíñòðóêòîð äëÿ ïîä-êîìïîíåíòà. + LocalLog( + const LogParam& param, //!< [in] Ïàðàìåòðû ñîçäàíèÿ ëîãà. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ ïî óìîë÷àíèþ. + ); + //! Êîíñòðóêòîð. + LocalLog( + LogMediaPtr pMedia, //!< [in] Ëîã. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ. + ); + //! Êîíñòðóêòîð. + LocalLog( + const LogBase& log, //!< [in] Ëîã. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ. + ); + virtual ~LocalLog(); +}; + +class Log: public LogBase +{ +public: + //! Êîíñòðóêòîð äëÿ ïîä-êîìïîíåíòà. + Log( + const LogParam& param, //!< [in] Ïàðàìåòðû ñîçäàíèÿ ëîãà. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ ïî óìîë÷àíèþ. + ); + //! Êîíñòðóêòîð äëÿ ãëàâíîãî ëîãà ïðèëîæåíèÿ èëè êîìïîíåíòà. + Log( + LogMediaPtr pMedia, //!< [in] Ëîã. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ. + ); + //! Êîíñòðóêòîð äëÿ ïîä-êîìïîíåíòà. + Log( + const LogBase& log, //!< [in] Ëîã. + LPCTSTR pszModule //!< [in] Èìÿ ìîäóëÿ. + ); + virtual ~Log(); + void SetParams( + LogMediaPtr pMedia, //!< [in] Íîâûé ëîã. + LPCTSTR pszModule = NULL //!< [in] Íîâîå èìÿ ìîäóëÿ. Ìîæåò áûòü NULL. + ); + //! Çàïèñûâàåò ôîðìàòèðîâàííîå ñîîáùåíèå. + virtual void WriteVA( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCTSTR pszModule, //!< [in] Èìÿ ìîäóëÿ. + LPCTSTR pszMessage, //!< [in] Ñîîáùåíèå. + va_list args + ) throw(); + //! Çàïèñûâàåò ôîðìàòèðîâàííîå Unicode-ñîîáùåíèå. + virtual void WriteVAW( + ELogMessageType type, //!< [in] Òèï ñîîáùåíèÿ. + ELogMessageLevel nLevel,//!< [in] Óðîâåíü âàæíîñòè (L0 - íàèáîëåå âàæíûé). + LPCWSTR pszModule, //!< [in] Èìÿ ìîäóëÿ. + LPCWSTR pszMessage, //!< [in] Ñîîáùåíèå. + va_list args + ) throw(); +private: + CriticalSection m_cs; +}; + + +//! "Ëîãè÷åñêèé" ëîã ñ ôèëüòðàöèåé. +class FilterLog: public Log +{ + typedef std::shared_ptr TFilterLogMediaPtr; + TFilterLogMediaPtr GetFilterLogMedia() { return std::static_pointer_cast(GetMedia()); } +public: + FilterLog(const LogParam& param, LPCTSTR pszModule): Log(param, pszModule) + { + LogMediaPtr pMedia = GetMedia(); + if (pMedia) + SetParams(LogMediaPtr(new FilterLogMedia(pMedia))); + } + virtual ~FilterLog(); + void AddFilter(FilterPtr pFilter) { if (GetFilterLogMedia()) GetFilterLogMedia()->AddFilter(pFilter); } +}; + +#endif \ No newline at end of file diff --git a/ext/CrashServer/CommonLibs/Log/log_media.h b/ext/CrashServer/CommonLibs/Log/log_media.h new file mode 100644 index 000000000..16b01d36d --- /dev/null +++ b/ext/CrashServer/CommonLibs/Log/log_media.h @@ -0,0 +1,68 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __LOG_MEDIA_H +#define __LOG_MEDIA_H + +#include "log.h" +#include "synchro.h" +#include + +class ConsoleMedia: public ILogMedia +{ +public: + ConsoleMedia(); +protected: + virtual void Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage); +private: + CriticalSection m_cs; + HANDLE m_hConsole; + CONSOLE_SCREEN_BUFFER_INFO m_info; + bool m_bRedirectedToFile; +}; + +class FileMedia: public ILogMedia +{ +public: + FileMedia(LPCTSTR pszFilename, bool bAppend, bool bFlush, bool bNewFileDaily = false); + virtual ~FileMedia(); + virtual bool IsWorking() const; +protected: + virtual void Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage); +private: + bool m_bAppend; + bool m_bFlush; + bool m_bNewFileDaily;//For this mode to work, file name template must contain %DATE% + WORD m_wLogYear, m_wLogMonth, m_wLogDay; + FileHandle m_hFile; + Handle m_hMutex; + CString m_sFilename, m_sOrigFilename; + void CloseLogFile(); + void OpenLogFile(); +}; + +class DebugMedia: public ILogMedia +{ + DWORD m_dwParam; +public: + DebugMedia(DWORD dwParam); + virtual bool IsWorking() const; +protected: + virtual void Write(ELogMessageType type, ELogMessageLevel nLevel, LPCTSTR pszDate, LPCTSTR pszTime, LPCTSTR pszThreadId, LPCTSTR pszThreadName, LPCTSTR pszModule, LPCTSTR pszMessage); +}; + +#endif \ No newline at end of file diff --git a/ext/CrashServer/CommonLibs/Log/synchro.h b/ext/CrashServer/CommonLibs/Log/synchro.h new file mode 100644 index 000000000..907fcccaa --- /dev/null +++ b/ext/CrashServer/CommonLibs/Log/synchro.h @@ -0,0 +1,82 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef _SYNCHRO_H__INCLUDE_ +#define _SYNCHRO_H__INCLUDE_ + +#include + +class Handle +{ +protected: + HANDLE m_hHandle; +public: + Handle(HANDLE hHandle = NULL): m_hHandle(hHandle) {} + ~Handle() { Close(); } + operator HANDLE() { return m_hHandle; } + Handle& operator = (HANDLE hHandle) { Close(); m_hHandle = hHandle; return *this; } + void Close() { if (m_hHandle != NULL) { CloseHandle(m_hHandle); m_hHandle = NULL; } } +}; + +class FileHandle +{ +protected: + HANDLE m_hHandle; +public: + FileHandle(HANDLE hHandle = INVALID_HANDLE_VALUE): m_hHandle(hHandle) {} + ~FileHandle() { Close(); } + operator HANDLE() const { return m_hHandle; } + FileHandle& operator = (HANDLE hHandle) { Close(); m_hHandle = hHandle; return *this; } + void Close() { if (m_hHandle != INVALID_HANDLE_VALUE) { CloseHandle(m_hHandle); m_hHandle = INVALID_HANDLE_VALUE; } } +}; + + +class Event: public Handle +{ +public: + Event(LPSECURITY_ATTRIBUTES pAttr = NULL, bool bManual = true, bool bState = false, LPCTSTR pName = NULL) + : Handle( CreateEvent(pAttr, bManual, bState, pName)) {} + void Set() { SetEvent(m_hHandle); } + void Reset() { ResetEvent(m_hHandle); } +}; + +template +class SyncLockT +{ +public: + SyncLockT(SyncLockT& lock): m_SyncObj(lock.m_SyncObj) { m_SyncObj.Lock(); } + SyncLockT(T& SyncObj): m_SyncObj(SyncObj) { m_SyncObj.Lock(); } + ~SyncLockT() { m_SyncObj.Unlock(); } +private: + SyncLockT &operator=(const SyncLockT& lock); + T& m_SyncObj; +}; + +class CriticalSection +{ +public: + CriticalSection() { InitializeCriticalSection(&m_cs); } + ~CriticalSection() { DeleteCriticalSection(&m_cs); } + void Lock() { EnterCriticalSection(&m_cs); } + void Unlock() { LeaveCriticalSection(&m_cs); } + + typedef SyncLockT SyncLock; +private: + CRITICAL_SECTION m_cs; +}; + +#endif \ No newline at end of file diff --git a/ext/CrashServer/CommonLibs/Version/version.h b/ext/CrashServer/CommonLibs/Version/version.h new file mode 100644 index 000000000..3eeb2db15 --- /dev/null +++ b/ext/CrashServer/CommonLibs/Version/version.h @@ -0,0 +1,83 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __VERSION_H +#define __VERSION_H + + +#ifndef VERSION_PRODUCTVERSION_HIGH +# define VERSION_PRODUCTVERSION_HIGH 1 +#endif + +#ifndef VERSION_PRODUCTVERSION_LOW +# define VERSION_PRODUCTVERSION_LOW 0 +#endif + +#ifndef VERSION_PRODUCTVERSION_BUILD +# define VERSION_PRODUCTVERSION_BUILD 0 +#endif + +#ifndef VERSION_PRODUCTVERSION_COMPILATION +# define VERSION_PRODUCTVERSION_COMPILATION 0 +#endif + +#define VERSION_ITOA2(x) #x +#define VERSION_ITOA(x) VERSION_ITOA2(x) + +#define VERSION_PRODUCTVERSION_HIGH_STR VERSION_ITOA(VERSION_PRODUCTVERSION_HIGH) +#define VERSION_PRODUCTVERSION_LOW_STR VERSION_ITOA(VERSION_PRODUCTVERSION_LOW) +#define VERSION_PRODUCTVERSION_BUILD_STR VERSION_ITOA(VERSION_PRODUCTVERSION_BUILD) +#define VERSION_PRODUCTVERSION_COMPILATION_STR VERSION_ITOA(VERSION_PRODUCTVERSION_COMPILATION) +#define VERSION_PRODUCTVERSION VERSION_PRODUCTVERSION_HIGH,VERSION_PRODUCTVERSION_LOW,VERSION_PRODUCTVERSION_BUILD,VERSION_PRODUCTVERSION_COMPILATION +#define VERSION_PRODUCTVERSION_STR VERSION_PRODUCTVERSION_HIGH_STR "." VERSION_PRODUCTVERSION_LOW_STR "." VERSION_PRODUCTVERSION_BUILD_STR "." VERSION_PRODUCTVERSION_COMPILATION_STR + + +#ifndef VERSION_FILEVERSION_HIGH +# define VERSION_FILEVERSION_HIGH VERSION_PRODUCTVERSION_HIGH +#endif + +#ifndef VERSION_FILEVERSION_LOW +# define VERSION_FILEVERSION_LOW VERSION_PRODUCTVERSION_LOW +#endif + +#ifndef VERSION_FILEVERSION_BUILD +# define VERSION_FILEVERSION_BUILD VERSION_PRODUCTVERSION_BUILD +#endif + +#ifndef VERSION_FILEVERSION_COMPILATION +# define VERSION_FILEVERSION_COMPILATION VERSION_PRODUCTVERSION_COMPILATION +#endif + +#define VERSION_FILEVERSION_HIGH_STR VERSION_ITOA(VERSION_FILEVERSION_HIGH) +#define VERSION_FILEVERSION_LOW_STR VERSION_ITOA(VERSION_FILEVERSION_LOW) +#define VERSION_FILEVERSION_BUILD_STR VERSION_ITOA(VERSION_FILEVERSION_BUILD) +#define VERSION_FILEVERSION_COMPILATION_STR VERSION_ITOA(VERSION_FILEVERSION_COMPILATION) +#define VERSION_FILEVERSION VERSION_FILEVERSION_HIGH,VERSION_FILEVERSION_LOW,VERSION_FILEVERSION_BUILD,VERSION_FILEVERSION_COMPILATION +#define VERSION_FILEVERSION_STR VERSION_FILEVERSION_HIGH_STR "." VERSION_FILEVERSION_LOW_STR "." VERSION_FILEVERSION_BUILD_STR "." VERSION_FILEVERSION_COMPILATION_STR + + +#ifndef VERSION_COMPANYNAME_STR +# define VERSION_COMPANYNAME_STR "Idol Software" +#endif + + +// if pass APSTUDIO_INVOKED version resource appeats in .rc file +#if defined(RC_INVOKED) && !defined(APSTUDIO_INVOKED) +# include "version.rc" +#endif + +#endif //__VERSION_H diff --git a/ext/CrashServer/CommonLibs/Version/version.rc b/ext/CrashServer/CommonLibs/Version/version.rc new file mode 100644 index 000000000..59a22fa60 --- /dev/null +++ b/ext/CrashServer/CommonLibs/Version/version.rc @@ -0,0 +1,105 @@ +#ifndef __VERSION_RC +#define __VERSION_RC + +#include "winver.h" +#include "windows.h" + + +#ifndef VERSION_FILEFLAGSMASK +# define VERSION_FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#endif + + +#ifndef VERSION_FILEOS +# define VERSION_FILEOS VOS__WINDOWS32 +#endif + + +#ifdef _DLL +# ifndef VERSION_FILETYPE +# define VERSION_FILETYPE VFT_DLL +# endif +# ifndef VERSION_INTERNALEXTENSION_STR +# define VERSION_INTERNALEXTENSION_STR "dll" +# endif +#else +# ifndef VERSION_FILETYPE +# define VERSION_FILETYPE VFT_APP +# endif +# ifndef VERSION_INTERNALEXTENSION_STR +# define VERSION_INTERNALEXTENSION_STR "exe" +# endif +#endif + + +#ifndef VERSION_FILESUBTYPE +# define VERSION_FILESUBTYPE VFT2_UNKNOWN +#endif + + +#ifndef VERSION_PRODUCTNAME_STR +# error "There is no VERSION_PRODUCTNAME_STR" +#endif + + +#ifndef VERSION_FILEDESCRIPTION_STR +# error "There is no VERSION_FILEDESCRIPTION_STR" +#endif + +#ifndef VERSION_INTERNALNAME_STR +# error There is no VERSION_INTERNALNAME_STR +#endif + +#ifndef VERSION_LEGALCOPYRIGHT_STR +# define VERSION_LEGALCOPYRIGHT_STR "Copyright (C) " VERSION_COMPANYNAME_STR " 2012" +#endif + +#ifndef VERSION_ORIGINALFILENAME_STR +# define VERSION_ORIGINALFILENAME_STR VERSION_INTERNALNAME_STR "." VERSION_INTERNALEXTENSION_STR +#endif + + +#ifndef VERSION_VERSION_UNICODE_LANG +# define VERSION_VERSION_UNICODE_LANG "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ +#endif + + +#ifndef VERSION_VERSION_TRANSLATION +# define VERSION_VERSION_TRANSLATION 0x409, 0x4B0 /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ +#endif + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_FILEVERSION + PRODUCTVERSION VERSION_PRODUCTVERSION + FILEFLAGSMASK VERSION_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS VERSION_FILEOS + FILETYPE VERSION_FILETYPE + FILESUBTYPE VERSION_FILESUBTYPE +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK VERSION_VERSION_UNICODE_LANG + BEGIN + VALUE "CompanyName", VERSION_COMPANYNAME_STR + VALUE "FileDescription", VERSION_FILEDESCRIPTION_STR + VALUE "FileVersion", VERSION_FILEVERSION_STR + VALUE "InternalName", VERSION_INTERNALNAME_STR + VALUE "LegalCopyright", VERSION_LEGALCOPYRIGHT_STR + VALUE "OriginalFilename",VERSION_ORIGINALFILENAME_STR + VALUE "ProductName", VERSION_PRODUCTNAME_STR + VALUE "ProductVersion", VERSION_PRODUCTVERSION_STR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", VERSION_VERSION_TRANSLATION + END +END + +#endif // __VERSION_RC diff --git a/ext/CrashServer/CommonLibs/Zlib/ZipUnzip.cpp b/ext/CrashServer/CommonLibs/Zlib/ZipUnzip.cpp new file mode 100644 index 000000000..b9a765203 --- /dev/null +++ b/ext/CrashServer/CommonLibs/Zlib/ZipUnzip.cpp @@ -0,0 +1,166 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include +#include +#include +#include "ZipUnzip.h" +#include "contrib\minizip\zip.h" +#include "contrib\minizip\unzip.h" +#include "contrib\minizip\iowin32.h" + +using namespace std; + +Zip::Zip(LPCWSTR pszFilename, bool append) +{ + zlib_filefunc_def ffunc; + fill_win32_filefunc(&ffunc); + m_zf = zipOpen2(CW2CT(pszFilename), append ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE, NULL, &ffunc); + + if (!m_zf) + throw runtime_error(append ? "failed to append zip file" : "failed to create zip file"); +} + +Zip::~Zip(void) +{ + zipClose(m_zf, NULL); +} + +void Zip::AddFile(LPCWSTR pszFilename, LPCWSTR pszFilenameInZip) +{ + zip_fileinfo zi = {}; + + WIN32_FIND_DATAW ff; + HANDLE hFind = FindFirstFileW(pszFilename, &ff); + if (hFind == INVALID_HANDLE_VALUE) + throw runtime_error("file to add to zip not found"); + + FILETIME ftLocal; + FileTimeToLocalFileTime(&(ff.ftLastWriteTime), &ftLocal); + FileTimeToDosDateTime(&ftLocal, ((LPWORD)&zi.dosDate)+1, ((LPWORD)&zi.dosDate)+0); + FindClose(hFind); + + int err = zipOpenNewFileInZip3(m_zf, CW2CT(pszFilenameInZip), &zi, + NULL, 0, NULL, 0, NULL /* comment*/, + Z_DEFLATED, Z_BEST_COMPRESSION, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0); + + if (err != ZIP_OK) + throw runtime_error("failed to create file in zip"); + + + CAtlFile hFile(CreateFileW(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); + if (hFile == INVALID_HANDLE_VALUE) + throw runtime_error("file to add to zip not found"); + + BYTE buf[1024*8]; + DWORD dwReaded; + while (SUCCEEDED(hFile.Read(buf, _countof(buf), dwReaded)) && dwReaded != 0) + { + err = zipWriteInFileInZip(m_zf, buf, dwReaded); + if (err != ZIP_OK) + throw runtime_error("failed to write to zip"); + } + + if (ZIP_OK != zipCloseFileInZip(m_zf)) + throw runtime_error("failed to finalize file in zip"); +} + +Unzip::Unzip() + : m_uf(NULL) +{ +} + +Unzip::~Unzip() +{ + unzClose(m_uf); +} + +void Unzip::Open(LPCWSTR pszFilename) +{ + zlib_filefunc_def ffunc; + fill_win32_filefunc(&ffunc); + m_uf = unzOpen2(CW2CT(pszFilename), &ffunc); + + if (!m_uf) + throw runtime_error("failed to open zip file"); +} + +void Unzip::Extract(LPCWSTR pszFolder) +{ + unz_global_info gi; + if (UNZ_OK != unzGetGlobalInfo(m_uf, &gi)) + throw runtime_error("failed to unzGetGlobalInfo"); + + vector buf(8192); + + for (uLong i = 0; i < gi.number_entry; ++i) + { + unz_file_info file_info; + CStringA pathA; + const int pathLen = 256; + if (UNZ_OK != unzGetCurrentFileInfo(m_uf, &file_info, pathA.GetBuffer(pathLen), pathLen, NULL, 0, NULL, 0)) + throw runtime_error("failed to unzGetCurrentFileInfo"); + pathA.ReleaseBuffer(-1); + CStringW path = pszFolder; + path += L'\\'; + path += pathA; + + CStringW filename = path.Mid(path.ReverseFind(L'\\') + 1); + + if (filename.IsEmpty()) + { + if (!CreateDirectoryW(path, NULL)) + throw runtime_error("failed to CreateDirectory"); + continue; + } + + if (UNZ_OK != unzOpenCurrentFilePassword(m_uf, NULL)) + throw runtime_error("failed to unzOpenCurrentFilePassword"); + + CAtlFile file(CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); + if (file == INVALID_HANDLE_VALUE) + throw runtime_error("failed to CreateFile"); + + m_files.push_back(path); + + while (1) + { + int size = unzReadCurrentFile(m_uf, &buf[0], (unsigned int)buf.size()); + if (size < 0) + throw runtime_error("failed to unzReadCurrentFile"); + if (size == 0) + break; + + if (FAILED(file.Write(&buf[0], size))) + throw runtime_error("failed to WriteFile"); + } + + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + GetFileTime(file, &ftCreate, &ftLastAcc, &ftLastWrite); + DosDateTimeToFileTime((WORD)(file_info.dosDate>>16), (WORD)file_info.dosDate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal, &ftm); + SetFileTime(file, &ftm, &ftLastAcc, &ftm); + + if (UNZ_OK != unzCloseCurrentFile(m_uf)) + throw runtime_error("failed to unzCloseCurrentFile"); + + if (i + 1 < gi.number_entry && UNZ_OK != unzGoToNextFile(m_uf)) + throw runtime_error("failed to unzGoToNextFile"); + } +} diff --git a/ext/CrashServer/CommonLibs/Zlib/ZipUnzip.h b/ext/CrashServer/CommonLibs/Zlib/ZipUnzip.h new file mode 100644 index 000000000..041a58e9e --- /dev/null +++ b/ext/CrashServer/CommonLibs/Zlib/ZipUnzip.h @@ -0,0 +1,51 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include + +typedef void* zipFile; +typedef void* unzFile; + +class Zip +{ +public: + Zip(LPCWSTR pszFilename, bool append = false); + ~Zip(); + + void AddFile(LPCWSTR pszFilename, LPCWSTR pszFilenameInZip); + +private: + zipFile m_zf; +}; + +class Unzip +{ +public: + Unzip(); + ~Unzip(); + + void Open(LPCWSTR pszFilename); + void Extract(LPCWSTR pszFolder); + + std::vector m_files; + +private: + unzFile m_uf; +}; diff --git a/ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj b/ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj new file mode 100644 index 000000000..77ee4f52c --- /dev/null +++ b/ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj @@ -0,0 +1,180 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8E75B9C1-D45F-48BC-8C8E-28330E2E12E3} + Zlib + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + MaxSpeed + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + Level3 + ProgramDatabase + + + + + X64 + + + MaxSpeed + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + Level3 + ProgramDatabase + + + + + MaxSpeed + true + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Level3 + ProgramDatabase + + + + + X64 + + + MaxSpeed + true + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj.filters b/ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj.filters new file mode 100644 index 000000000..6c190b0bc --- /dev/null +++ b/ext/CrashServer/CommonLibs/Zlib/Zlib.vcxproj.filters @@ -0,0 +1,138 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {3dc059d6-bb27-400a-98a5-7dd2571380c7} + + + {5fdbc241-eaa2-4a6e-858f-56e0ef87e1ec} + + + {b111a0de-3137-481f-a49e-a34a34b797f0} + + + + + My + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + My + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/ext/CrashServer/CommonLibs/Zlib/Zlib_static.vcxproj b/ext/CrashServer/CommonLibs/Zlib/Zlib_static.vcxproj new file mode 100644 index 000000000..81447297a --- /dev/null +++ b/ext/CrashServer/CommonLibs/Zlib/Zlib_static.vcxproj @@ -0,0 +1,180 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D} + ZlibStatic + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\ + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + Level3 + ProgramDatabase + + + + + X64 + + + MaxSpeed + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + Level3 + ProgramDatabase + + + + + MaxSpeed + true + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + + + + + X64 + + + MaxSpeed + true + $(ProjectDir)..\..\external\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/COPYING b/ext/CrashServer/CrashHandler/COPYING new file mode 100644 index 000000000..3d90694ad --- /dev/null +++ b/ext/CrashServer/CrashHandler/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/COPYING.LESSER b/ext/CrashServer/CrashHandler/COPYING.LESSER new file mode 100644 index 000000000..f0156c535 --- /dev/null +++ b/ext/CrashServer/CrashHandler/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.cpp b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.cpp new file mode 100644 index 000000000..5ae238723 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.cpp @@ -0,0 +1,587 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "stdafx.h" +#include "resource.h" +#include "CrashHandlerExport.h" +#include "..\SendRpt\Config.h" +#include "..\SendRpt\Serializer.h" +#include +#include + +HINSTANCE g_hThisDLL = NULL; +bool g_applicationVerifierPresent = false; +bool g_ownProcess = false; +volatile LONG g_insideCrashHandler = 0; +LPTOP_LEVEL_EXCEPTION_FILTER g_prevTopLevelExceptionFilter = NULL; + +// It should not be destroyed on PROCESS_DETACH, because it may be used later if someone will crash on deinitialization +// so it is on heap, but not static (runtime destroy static objects on PROCESS_DETACH) +Config* g_pConfig = new Config(); + +DWORD g_tlsPrevTerminatePtr = TLS_OUT_OF_INDEXES; +typedef terminate_function (__cdecl *pfn_set_terminate)(terminate_function); +pfn_set_terminate g_set_terminate = NULL; + +enum CrashServerCustomExceptionCodes +{ + CRASHSERVER_EXCEPTION_ASSERTION_VIOLATED = CrashHandler::ExceptionAssertionViolated, // 0xCCE17000 + CRASHSERVER_EXCEPTION_CPP_TERMINATE = 0xCCE17001, + CRASHSERVER_EXCEPTION_CPP_PURE_CALL = 0xCCE17002, + CRASHSERVER_EXCEPTION_CPP_INVALID_PARAMETER = 0xCCE17003, +}; + +void ExtractFileFromResource(HMODULE hModule, DWORD resId, LPCTSTR path) +{ + HRSRC hDbghelpRes = FindResource(hModule, MAKEINTRESOURCE(resId), RT_RCDATA); + if (!hDbghelpRes) + throw runtime_error("failed to find file in resources"); + + HGLOBAL hDbghelpGlobal = LoadResource(hModule, hDbghelpRes); + if (!hDbghelpGlobal) + throw runtime_error("failed to load file from resources"); + + CAtlFile hFile(CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); + if (hFile == INVALID_HANDLE_VALUE) + throw runtime_error("failed to create file"); + + if (FAILED(hFile.Write(LockResource(hDbghelpGlobal), SizeofResource(hModule, hDbghelpRes)))) + throw runtime_error("failed to write file"); +} + +DWORD WINAPI SendReportThread(LPVOID lpParameter) +{ + InterlockedIncrement(&g_insideCrashHandler); + + //::MessageBoxA(0, "SendReportThread", "SendReportThread", 0); + MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo = (MINIDUMP_EXCEPTION_INFORMATION*)lpParameter; + try + { + WCHAR sendRptExe[MAX_PATH], drive[4], dir[MAX_PATH], fname[MAX_PATH], ext[MAX_PATH]; + GetModuleFileNameW(NULL, sendRptExe, _countof(sendRptExe)); + _wsplitpath_s(sendRptExe, drive, dir, fname, ext); + _wmakepath_s(sendRptExe, drive, dir, L"SendRpt", L".exe"); + bool localSendRpt = 0 == _waccess_s(sendRptExe, 00/* Existence only */); + if (!localSendRpt) + { + GetTempPathW(_countof(sendRptExe), sendRptExe); + wcscat_s(sendRptExe, L"SendRpt.exe"); + + ExtractFileFromResource(g_hThisDLL, IDR_SENDRPT, sendRptExe); + } + + CString cmd; + cmd.Format(_T("\"%s\" "), sendRptExe); + + CHandle hProcess; + DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &hProcess.m_h, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | THREAD_ALL_ACCESS, TRUE, 0); + + CHandle hReportReady(CreateEvent(NULL, TRUE, FALSE, NULL)); + SetHandleInformation(hReportReady, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + + Params param; + param.Process = hProcess; + param.ProcessId = GetCurrentProcessId(); + param.ExceptInfo = *pExceptInfo; + param.WasAssert = pExceptInfo->ExceptionPointers->ExceptionRecord->ExceptionCode == CRASHSERVER_EXCEPTION_ASSERTION_VIOLATED; + param.ReportReady = hReportReady; + + Serializer ser; + ser << param << *g_pConfig; + cmd.Append(ser.GetHex()); + + STARTUPINFO si = {sizeof(si)}; + PROCESS_INFORMATION pi; + if (!CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) + throw std::runtime_error("failed to start SendRpt"); + CloseHandle(pi.hThread); + + HANDLE handles[] = { pi.hProcess, hReportReady.m_h }; + DWORD res = WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE); + + CloseHandle(pi.hProcess); + + // if hReportReady event signaled, SendRpt is still working, so delete only when SendRpt has finished. + if (!localSendRpt && handles[res - WAIT_OBJECT_0] == pi.hProcess) + DeleteFileW(sendRptExe); + + InterlockedDecrement(&g_insideCrashHandler); + + return TRUE; + } + catch (std::exception& ex) + { + OutputDebugStringA(ex.what()); + } + + InterlockedDecrement(&g_insideCrashHandler); + + return FALSE; +} + +LONG SendReport(EXCEPTION_POINTERS* pExceptionPointers) +{ + if (IsDebuggerPresent()) + return EXCEPTION_CONTINUE_SEARCH; + + // We can enter here because of stack overflow, so lets all local variables + // be static, because variables on stack can lead to second stack overflow. + static DWORD dwThreadId; + static HANDLE hThread; + static MINIDUMP_EXCEPTION_INFORMATION exceptInfo; + exceptInfo.ThreadId = GetCurrentThreadId(); + exceptInfo.ExceptionPointers = pExceptionPointers; + exceptInfo.ClientPointers = FALSE; + + // If stack overflow, do all processing in another thread + if (pExceptionPointers != NULL + && pExceptionPointers->ExceptionRecord != NULL + && pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW + && (hThread = CreateThread(NULL, 0, SendReportThread, &exceptInfo, 0, &dwThreadId)) != NULL) + { + WaitForSingleObject(hThread, INFINITE); + } + else + { + SendReportThread(&exceptInfo); + } + + if (pExceptionPointers->ExceptionRecord->ExceptionCode == CRASHSERVER_EXCEPTION_ASSERTION_VIOLATED) + return EXCEPTION_CONTINUE_EXECUTION; + + return g_pConfig->UseWER ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER; +} + +LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers) +{ + if (pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT + && g_applicationVerifierPresent) + { + // This crash has been processed in VectoredExceptionHandler and if we here we want WinQual + return EXCEPTION_CONTINUE_SEARCH; + } + + return SendReport(pExceptionPointers); +} + +LONG CALLBACK VectoredExceptionHandler(EXCEPTION_POINTERS* pExceptionPointers) +{ + // Probably this is Application Verifier stop + if (pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT + && g_applicationVerifierPresent) + { + LONG res = SendReport(pExceptionPointers); + if (res == EXCEPTION_EXECUTE_HANDLER) + ExitProcess(0); // we don't want WinQual from Application Verifier + } + + // Asserts should be handled in VectoredExceptionHandler since EXCEPTION_CONTINUE_EXECUTION is used + // and __try { ... } __except(EXCEPTION_EXECUTE_HANDLER) { ... } in the way to TopLevelExceptionFilter + // may break this logic. + if (pExceptionPointers->ExceptionRecord->ExceptionCode == CRASHSERVER_EXCEPTION_ASSERTION_VIOLATED) + return SendReport(pExceptionPointers); + + return EXCEPTION_CONTINUE_SEARCH; +} + +FARPROC GetSetUnhandledExceptionFilterPointer() +{ + FARPROC suef = NULL; + // In Windows 8 SetUnhandledExceptionFilter implementation is in kernelbase + if (HMODULE kernelbase = GetModuleHandle(_T("kernelbase"))) + suef = GetProcAddress(kernelbase, "SetUnhandledExceptionFilter"); + if (!suef) + { + if (HMODULE kernel32 = GetModuleHandle(_T("kernel32"))) + suef = GetProcAddress(kernel32, "SetUnhandledExceptionFilter"); + } + return suef; +} + +void SwitchSetUnhandledExceptionFilter(bool enable) +{ + FARPROC suef = GetSetUnhandledExceptionFilterPointer(); + if (!suef) + return; + + // newBody is something like that: + // + // LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER) + // { + // return NULL; + // } +#if defined(_M_X64) + static const BYTE newBody[] = + { + 0x33, 0xC0, // xor eax,eax + 0xC3 // ret + }; +#elif defined(_M_IX86) + static const BYTE newBody[] = + { + 0x8B, 0xFF, // mov edi,edi <- for hotpatching + 0x33, 0xC0, // xor eax,eax + 0xC2, 0x04, 0x00 // ret 4 + }; +#else +# error Unsupported architecture +#endif + const SIZE_T bodySize = sizeof(newBody); + + static BYTE oldBody[bodySize] = { 0 }; + + DWORD oldProtection; + if (!VirtualProtect(suef, bodySize, PAGE_EXECUTE_READWRITE, &oldProtection)) + return; + if (!enable) + { + memcpy(oldBody, suef, bodySize); + memcpy(suef, newBody, bodySize); + } + else if (oldBody[0] != 0) + { + memcpy(suef, oldBody, bodySize); + } + + VirtualProtect(suef, bodySize, oldProtection, &oldProtection); +} + +void DisableSetUnhandledExceptionFilter() +{ + SwitchSetUnhandledExceptionFilter(false); +} + +void ReenableSetUnhandledExceptionFilter() +{ + SwitchSetUnhandledExceptionFilter(true); +} + +// This code should be inplace, so it is a macro +#define SendReportWithCode(code) __try { RaiseException(code, EXCEPTION_NONCONTINUABLE, 0, NULL); } __except(TopLevelExceptionFilter(GetExceptionInformation())) {} + +void CrashServer_SendAssertionViolated() +{ + RaiseException(CRASHSERVER_EXCEPTION_ASSERTION_VIOLATED, 0, 0, NULL); +} + +void CrashServer_TerminateHandler() +{ + SendReportWithCode(CRASHSERVER_EXCEPTION_CPP_TERMINATE); + + if (g_tlsPrevTerminatePtr != TLS_OUT_OF_INDEXES) + { + terminate_function prev_terminate = static_cast(TlsGetValue(g_tlsPrevTerminatePtr)); + if (prev_terminate) + prev_terminate(); + } + + if (!g_pConfig->UseWER) + ExitProcess(0); +} + +void CrashServer_PureCallHandler() +{ + SendReportWithCode(CRASHSERVER_EXCEPTION_CPP_PURE_CALL); + ExitProcess(0); +} + +void CrashServer_InvalidParameterHandler(const wchar_t *, const wchar_t *, const wchar_t *, unsigned int, uintptr_t) +{ + SendReportWithCode(CRASHSERVER_EXCEPTION_CPP_INVALID_PARAMETER); + ExitProcess(0); +} + +void CrashServer_SigAbrtHandler(int) +{ + SendReportWithCode(CRASHSERVER_EXCEPTION_CPP_TERMINATE); + ExitProcess(0); +} + +void MakePerThreadInitialization() +{ + if (g_tlsPrevTerminatePtr != TLS_OUT_OF_INDEXES && g_set_terminate) + TlsSetValue(g_tlsPrevTerminatePtr, g_set_terminate(CrashServer_TerminateHandler)); +} + +void InitCrtErrorHandlers() +{ + LPCTSTR crtModules[] = { + _T("msvcr70"), _T("msvcr70d"), + _T("msvcr71"), _T("msvcr71d"), + _T("msvcr80"), _T("msvcr80d"), + _T("msvcr90"), _T("msvcr90d"), + _T("msvcr100"), _T("msvcr100d"), + _T("msvcr110"), _T("msvcr110d"), + _T("msvcr120"), _T("msvcr120d"), + }; + + HMODULE hMsvcrDll = NULL; + for (size_t i = 0; !hMsvcrDll && i < _countof(crtModules); ++i) + hMsvcrDll = GetModuleHandle(crtModules[i]); + + if (!hMsvcrDll) + return; + + g_set_terminate = (pfn_set_terminate) GetProcAddress(hMsvcrDll, "?set_terminate@@YAP6AXXZP6AXXZ@Z"); + + typedef _purecall_handler (__cdecl *pfn_set_purecall_handler)(_purecall_handler); + pfn_set_purecall_handler l_set_purecall_handler = (pfn_set_purecall_handler) GetProcAddress(hMsvcrDll, "_set_purecall_handler"); + if (l_set_purecall_handler) + l_set_purecall_handler(CrashServer_PureCallHandler); + + typedef _invalid_parameter_handler (__cdecl *pfn_set_invalid_parameter_handler)(_invalid_parameter_handler); + pfn_set_invalid_parameter_handler l_set_invalid_parameter_handler = (pfn_set_invalid_parameter_handler) GetProcAddress(hMsvcrDll, "_set_invalid_parameter_handler"); + if (l_set_invalid_parameter_handler) + l_set_invalid_parameter_handler(CrashServer_InvalidParameterHandler); + + typedef void (__cdecl *pfn_signal)(int sig, void (__cdecl *func)(int)); + pfn_signal l_signal = (pfn_signal) GetProcAddress(hMsvcrDll, "signal"); + if (l_signal) + l_signal(SIGABRT, CrashServer_SigAbrtHandler); +} + +BOOL InitCrashHandler(ApplicationInfo* applicationInfo, HandlerSettings* handlerSettings, BOOL ownProcess) +{ +#define IS_EXIST(field) (FIELD_OFFSET(ApplicationInfo, field) < applicationInfo->ApplicationInfoSize) + if (applicationInfo == NULL + || applicationInfo->ApplicationInfoSize == 0 + || applicationInfo->ApplicationInfoSize > sizeof(ApplicationInfo) + || !IS_EXIST(ApplicationGUID) || applicationInfo->ApplicationGUID == NULL + || !IS_EXIST(Prefix) || applicationInfo->Prefix == NULL + || !IS_EXIST(AppName) || applicationInfo->AppName == NULL + || !IS_EXIST(Company) || applicationInfo->Company == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + g_pConfig->ApplicationGUID = applicationInfo->ApplicationGUID; + g_pConfig->Prefix = applicationInfo->Prefix; + g_pConfig->AppName = applicationInfo->AppName; + g_pConfig->Company = applicationInfo->Company; + if (IS_EXIST(V)) + memcpy(g_pConfig->V, applicationInfo->V, sizeof(applicationInfo->V)); + else + memset(g_pConfig->V, 0, sizeof(g_pConfig->V)); + if (IS_EXIST(Hotfix)) + g_pConfig->Hotfix = applicationInfo->Hotfix; + else + g_pConfig->Hotfix = 0; + if (IS_EXIST(PrivacyPolicyUrl) && applicationInfo->PrivacyPolicyUrl != NULL) + g_pConfig->PrivacyPolicyUrl = applicationInfo->PrivacyPolicyUrl; + else + g_pConfig->PrivacyPolicyUrl.Format(L"http://www.crash-server.com/AppPrivacyPolicy.aspx?AppID=%s", (LPCWSTR)g_pConfig->ApplicationGUID); +#undef IS_EXIST + +#define IS_EXIST(field) (handlerSettings != NULL && (FIELD_OFFSET(HandlerSettings, field) < handlerSettings->HandlerSettingsSize)) + + if (handlerSettings != NULL + && (handlerSettings->HandlerSettingsSize == 0 || handlerSettings->HandlerSettingsSize > sizeof(HandlerSettings))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (IS_EXIST(LeaveDumpFilesInTempFolder)) + { + g_pConfig->ServiceMode = handlerSettings->LeaveDumpFilesInTempFolder == 2; // hidden behavior (used for dumpparser) + g_pConfig->LeaveDumpFilesInTempFolder = handlerSettings->LeaveDumpFilesInTempFolder != FALSE; + } + else + { + g_pConfig->ServiceMode = 0; + g_pConfig->LeaveDumpFilesInTempFolder = FALSE; + } + if (IS_EXIST(OpenProblemInBrowser)) + g_pConfig->OpenProblemInBrowser = handlerSettings->OpenProblemInBrowser; + else + g_pConfig->OpenProblemInBrowser = FALSE; + if (IS_EXIST(UseWER)) + g_pConfig->UseWER = handlerSettings->UseWER; + else + g_pConfig->UseWER = FALSE; + if (IS_EXIST(SubmitterID)) + g_pConfig->SubmitterID = handlerSettings->SubmitterID; + else + g_pConfig->SubmitterID = 0; +#undef IS_EXIST + + WCHAR path[MAX_PATH], drive[MAX_PATH], dir[MAX_PATH], fname[MAX_PATH], ext[MAX_PATH]; + GetModuleFileNameW(NULL, path, _countof(path)); + _wsplitpath_s(path, drive, dir, fname, ext); + g_pConfig->ProcessName = CStringW(fname) + ext; + g_pConfig->ProcessName.MakeLower(); + + g_ownProcess = ownProcess != FALSE; + + static bool inited = false; + if (!inited) + { + if (g_ownProcess) + { + // Application verifier sets its own VectoredExceptionHandler + // and Application verifier breaks redirected to WinQual. + // After that TopLevelExceptionFilter works. + // This behavior looks bad and anyway we don't need WinQual. + // So we set our VectoredExceptionHandler before AppVerifier and + // catch problems first. + g_applicationVerifierPresent = GetModuleHandle(_T("verifier.dll")) != NULL; + if (g_applicationVerifierPresent) + AddVectoredExceptionHandler(TRUE, VectoredExceptionHandler); + + g_prevTopLevelExceptionFilter = SetUnhandledExceptionFilter(TopLevelExceptionFilter); + // There is a lot of libraries that want to set their own wrong UnhandledExceptionFilter in our application. + // One of these is MSVCRT with __report_gsfailure and _call_reportfault leading to many + // of MSVCRT error reports to be redirected to Dr. Watson. + DisableSetUnhandledExceptionFilter(); + + InitCrtErrorHandlers(); + MakePerThreadInitialization(); + } + + // Need to lock library in process. + // Since some crashes appears on process deinitialization and we should be ready to handle it. + LoadLibrary(_T("crshhndl.dll")); + inited = true; + } + + return TRUE; +} + +void AddUserInfoToReport(LPCWSTR key, LPCWSTR value) +{ + if (!g_pConfig) + return; + g_pConfig->UserInfo.push_back(make_pair(CStringW(key), value)); +} + +void AddFileToReport(LPCWSTR path, LPCWSTR reportFileName) +{ + if (!g_pConfig) + return; + CStringW fileName; + if (!reportFileName) + { + WCHAR drive[MAX_PATH], dir[MAX_PATH], fname[MAX_PATH], ext[MAX_PATH]; + _wsplitpath_s(path, drive, dir, fname, ext); + fileName = CStringW(fname) + ext; + } + else + { + fileName = reportFileName; + } + g_pConfig->FilesToAttach.push_back(make_pair(CStringW(path), fileName)); +} + +void RemoveFileFromReport(LPCWSTR path) +{ + if (!g_pConfig) + return; + auto it = std::find_if(g_pConfig->FilesToAttach.begin(), g_pConfig->FilesToAttach.end(), + [path](std::pair& x){ return x.first == path; }); + if (it != g_pConfig->FilesToAttach.end()) + g_pConfig->FilesToAttach.erase(it); +} + +BOOL GetVersionFromFile(LPCWSTR path, ApplicationInfo* appInfo) +{ + if (!path || !appInfo) + return FALSE; + + appInfo->V[0] = 0; + appInfo->V[1] = 0; + appInfo->V[2] = 0; + appInfo->V[3] = 0; + + DWORD size = GetFileVersionInfoSize(path, NULL); + if (size == 0) + return FALSE; + LPVOID pVerInfo = HeapAlloc(GetProcessHeap(), 0, size); + if (!GetFileVersionInfo(path, 0, size, pVerInfo)) + { + HeapFree(GetProcessHeap(), 0, pVerInfo); + return FALSE; + } + VS_FIXEDFILEINFO* lpFileinfo = NULL; + UINT uLen; + if (!VerQueryValue(pVerInfo, _T("\\"), (LPVOID*)&lpFileinfo, &uLen)) + { + HeapFree(GetProcessHeap(), 0, pVerInfo); + return FALSE; + } + appInfo->V[0] = HIWORD(lpFileinfo->dwProductVersionMS); + appInfo->V[1] = LOWORD(lpFileinfo->dwProductVersionMS); + appInfo->V[2] = HIWORD(lpFileinfo->dwProductVersionLS); + appInfo->V[3] = LOWORD(lpFileinfo->dwProductVersionLS); + HeapFree(GetProcessHeap(), 0, pVerInfo); + + return TRUE; +} + +BOOL GetVersionFromApp(ApplicationInfo* appInfo) +{ + if (!appInfo) + return FALSE; + + appInfo->V[0] = 0; + appInfo->V[1] = 0; + appInfo->V[2] = 0; + appInfo->V[3] = 0; + + TCHAR path[MAX_PATH]; + if (!GetModuleFileName(NULL, path, _countof(path))) + return FALSE; + + return GetVersionFromFile(path, appInfo); +} + +BOOL IsReadyToExit() +{ + return g_insideCrashHandler == 0 ? TRUE : FALSE; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + g_hThisDLL = hinstDLL; + g_tlsPrevTerminatePtr = TlsAlloc(); + break; + case DLL_PROCESS_DETACH: + if (g_tlsPrevTerminatePtr != TLS_OUT_OF_INDEXES) + { + TlsFree(g_tlsPrevTerminatePtr); + g_tlsPrevTerminatePtr = TLS_OUT_OF_INDEXES; + } + if (g_prevTopLevelExceptionFilter) + { + ReenableSetUnhandledExceptionFilter(); + SetUnhandledExceptionFilter(g_prevTopLevelExceptionFilter); + } + if (g_applicationVerifierPresent) + RemoveVectoredExceptionHandler(VectoredExceptionHandler); + break; + case DLL_THREAD_ATTACH: + if (g_ownProcess) + { + MakePerThreadInitialization(); + } + break; + } + return TRUE; +} diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.def b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.def new file mode 100644 index 000000000..5d46443c2 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.def @@ -0,0 +1,11 @@ +LIBRARY "crshhndl" +EXPORTS + InitCrashHandler @1 + GetVersionFromApp @2 + GetVersionFromFile @3 + CrashServer_SendAssertionViolated @4 + AddFileToReport @5 + RemoveFileFromReport @6 + IsReadyToExit @7 + SendReport @8 + AddUserInfoToReport @9 diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.h b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.h new file mode 100644 index 000000000..c75c3ff9f --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.h @@ -0,0 +1,320 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __CRASH_HANDLER_H__ +#define __CRASH_HANDLER_H__ + +#include + +//! Contains data that identifies your application. +struct ApplicationInfo +{ + DWORD ApplicationInfoSize; //!< Size of this structure. Should be set to sizeof(ApplicationInfo). + LPCSTR ApplicationGUID; //!< GUID assigned to this application. + LPCSTR Prefix; //!< Prefix that will be used with the dump name: YourPrefix_v1.v2.v3.v4_YYYYMMDD_HHMMSS.mini.dmp. + LPCWSTR AppName; //!< Application name that will be used in message box. + LPCWSTR Company; //!< Company name that will be used in message box. + USHORT V[4]; //!< Version of this application. + USHORT Hotfix; //!< Version of hotfix for this application (reserved for future use, should be 0). + LPCWSTR PrivacyPolicyUrl; //!< URL to privacy policy. If NULL default privacy policy is used. +}; + +//! \brief Contains crash handling behavior customization parameters. +//! +//! Default values for all parameters is 0/FALSE. +struct HandlerSettings +{ + DWORD HandlerSettingsSize; //!< Size of this structure. Should be set to sizeof(HandlerSettings). + BOOL LeaveDumpFilesInTempFolder; //!< To leave error reports in temp folder you should set this member to TRUE. Your support or test lab teams can use that reports later. + BOOL OpenProblemInBrowser; //!< To open Web-page belonging to the uploaded report after it was uploaded set this member to TRUE. It is useful for test lab to track the bug or write some comments. + BOOL UseWER; //!< To continue use Microsoft Windows Error Reporting (WER) set this member to TRUE. In that case after Crash Server send report dialog Microsoft send report dialog also will be shown. This can be necessary in case of Windows Logo program. + DWORD SubmitterID; //!< Crash Server user ID. Uploaded report will be marked as uploaded by this user. This is useful for Crash Server and bug tracking system integration. Set to \b 0 if user using this application is anonymous. +}; + +//! \brief To enable crash processing you should create an instance of this class. +//! +//! It should be created as global static object and correctly initialized. +//! Also you may instantiate it in your main() or WinMain() function as soon as possible. +class CrashHandler +{ +public: + //! \example Sample.cpp + //! This is an example of how to use the CrashHandler class. + + //! CrashHandler constructor. Loads crshhndl.dll and initializes crash handling. + //! \note The crshhndl.dll may missing. In that case there will be no crash handling. + CrashHandler( + LPCSTR applicationGUID, //!< [in] GUID assigned to this application. + LPCSTR prefix, //!< [in] Prefix that will be used with the dump name: YourPrefix_v1.v2.v3.v4_YYYYMMDD_HHMMSS.mini.dmp. + LPCWSTR appName, //!< [in] Application name that will be used in message box. + LPCWSTR company, //!< [in] Company name that will be used in message box. + BOOL ownProcess = TRUE //!< [in] If you own the process your code running in set this option to \b TRUE. If don't (for example you write + //!< a plugin to some external application) set this option to \b FALSE. In that case you need to explicitly + //!< catch exceptions. See \ref SendReport for more information. + ) throw() + { + if (!LoadDll()) + return; + + ApplicationInfo appInfo; + memset(&appInfo, 0, sizeof(appInfo)); + appInfo.ApplicationInfoSize = sizeof(appInfo); + appInfo.ApplicationGUID = applicationGUID; + appInfo.Prefix = prefix; + appInfo.AppName = appName; + appInfo.Company = company; + if (!m_GetVersionFromApp(&appInfo)) + appInfo.V[0] = 1; + + HandlerSettings handlerSettings; + memset(&handlerSettings, 0, sizeof(handlerSettings)); + handlerSettings.HandlerSettingsSize = sizeof(handlerSettings); + + m_InitCrashHandler(&appInfo, &handlerSettings, ownProcess); + } + + //! CrashHandler constructor. Loads crshhndl.dll and initializes crash handling. + //! \note The crshhndl.dll may missing. In that case there will be no crash handling. + CrashHandler( + ApplicationInfo* applicationInfo, //!< [in] Pointer to the ApplicationInfo structure that identifies your application. + HandlerSettings* handlerSettings, //!< [in] Pointer to the HandlerSettings structure that customizes crash handling behavior. This paramenter can be \b NULL. + BOOL ownProcess = TRUE //!< [in] If you own the process your code running in set this option to \b TRUE. If don't (for example you write + //!< a plugin to some external application) set this option to \b FALSE. In that case you need to explicitly + //!< catch exceptions. See \ref SendReport for more information. + ) throw() + { + if (!LoadDll()) + return; + + m_InitCrashHandler(applicationInfo, handlerSettings, ownProcess); + } + + //! CrashHandler constructor. Loads crshhndl.dll. You should call \ref InitCrashHandler to turn on crash handling. + //! \note The crshhndl.dll may missing. In that case there will be no crash handling. + CrashHandler() throw() + { + LoadDll(); + } + + //! CrashHandler destructor. + //! \note It doesn't unload crshhndl.dll and doesn't disable crash handling since crash may appear on very late phase of application exit. + //! For example destructor of some static variable that is called after return from main() may crash. + ~CrashHandler() + { + if (!m_IsReadyToExit) + return; + + // If crash has happen not in main thread we should wait here until report will be sent + // or else program will be terminated after return from main() and report send will be halted. + while (!m_IsReadyToExit()) + ::Sleep(100); + } + + //! Initializes crash handler. + //! \note You may call this function multiple times if some data has changed. + //! \return Return \b true if crash handling was enabled. + bool InitCrashHandler( + ApplicationInfo* applicationInfo, //!< [in] Pointer to the ApplicationInfo structure that identifies your application. + HandlerSettings* handlerSettings, //!< [in] Pointer to the HandlerSettings structure that customizes crash handling behavior. This paramenter can be \b NULL. + BOOL ownProcess = TRUE //!< [in] If you own the process your code running in set this option to \b TRUE. If don't (for example you write + //!< a plugin to some external application) set this option to \b FALSE. In that case you need to explicitly + //!< catch exceptions. See \ref SendReport for more information. + ) throw() + { + if (!m_InitCrashHandler) + return false; + + return m_InitCrashHandler(applicationInfo, handlerSettings, ownProcess) != FALSE; + } + + //! You may add any key/value pair to crash report. + //! \return If the function succeeds, the return value is \b true. + bool AddUserInfoToReport( + LPCWSTR key, //!< [in] key string that will be added to the report. + LPCWSTR value //!< [in] value for the key. + ) throw() + { + if (!m_AddUserInfoToReport) + return false; + m_AddUserInfoToReport(key, value); + return true; + } + + //! You may add any file to crash report. This file will be read when crash appears and will be sent within the report. + //! Multiple files may be added. Filename of the file in the report may be changed to any name. + //! \return If the function succeeds, the return value is \b true. + bool AddFileToReport( + LPCWSTR path, //!< [in] Path to the file, that will be added to the report. + LPCWSTR reportFileName /* = NULL */ //!< [in] Filename that will be used in report for this file. If parameter is \b NULL, original name from path will be used. + ) throw() + { + if (!m_AddFileToReport) + return false; + m_AddFileToReport(path, reportFileName); + return true; + } + + //! Remove from report the file that was registered earlier to be sent within report. + //! \return If the function succeeds, the return value is \b true. + bool RemoveFileFromReport( + LPCWSTR path //!< [in] Path to the file, that will be removed from the report. + ) throw() + { + if (!m_RemoveFileFromReport) + return false; + m_RemoveFileFromReport(path); + return true; + } + + //! Fills version field (V) of ApplicationInfo with product version + //! found in the executable file of the current process. + //! \return If the function succeeds, the return value is \b true. + bool GetVersionFromApp( + ApplicationInfo* appInfo //!< [out] Pointer to ApplicationInfo structure. Its version field (V) will be set to product version. + ) throw() + { + if (!m_GetVersionFromApp) + return false; + return m_GetVersionFromApp(appInfo) != FALSE; + } + + //! Fill version field (V) of ApplicationInfo with product version found in the file specified. + //! \return If the function succeeds, the return value is \b true. + bool GetVersionFromFile( + LPCWSTR path, //!< [in] Path to the file product version will be extracted from. + ApplicationInfo* appInfo //!< [out] Pointer to ApplicationInfo structure. Its version field (V) will be set to product version. + ) throw() + { + if (!m_GetVersionFromFile) + return false; + return m_GetVersionFromFile(path, appInfo) != FALSE; + } + + //! If you do not own the process your code running in (for example you write a plugin to some + //! external application) you need to properly initialize CrashHandler using \b ownProcess option. + //! Also you need to explicitly catch all exceptions in all entry points to your code and in all + //! threads you create. To do so use this construction: + //! \code + //! bool SomeEntryPoint(PARAM p) + //! { + //! __try + //! { + //! return YouCode(p); + //! } + //! __except (CrashHandler::SendReport(GetExceptionInformation())) + //! { + //! ::ExitProcess(0); // It is better to stop the process here or else corrupted data may incomprehensibly crash it later. + //! return false; + //! } + //! } + //! \endcode + LONG SendReport( + EXCEPTION_POINTERS* exceptionPointers //!< [in] Pointer to EXCEPTION_POINTERS structure. You should get it using GetExceptionInformation() + //!< function inside __except keyword. + ) + { + if (!m_SendReport) + return EXCEPTION_CONTINUE_SEARCH; + // There is no crash handler but asserts should continue anyway + if (exceptionPointers->ExceptionRecord->ExceptionCode == ExceptionAssertionViolated) + return EXCEPTION_CONTINUE_EXECUTION; + return m_SendReport(exceptionPointers); + } + + //! To send a report about violated assertion you can throw exception with this exception code + //! using: \code RaiseException(CrashHandler::ExceptionAssertionViolated, 0, 0, NULL); \endcode + //! Execution will continue after report will be sent (EXCEPTION_CONTINUE_EXECUTION would be used). + //! \note If you called CrashHandler constructor and crshhdnl.dll was missing you still may using this exception. + //! It will be catched, ignored and execution will continue. \ref SendReport function also works safely + //! when crshhdnl.dll was missing. + static const DWORD ExceptionAssertionViolated = ((DWORD)0xCCE17000); + + //! Sends assertion violation report from this point and continue execution. + //! \sa ExceptionAssertionViolated + //! \note Functions prefixed with "CrashServer_" will be ignored in stack parsing. + void CrashServer_SendAssertionViolated() + { + if (!m_InitCrashHandler) + return; + ::RaiseException(CrashHandler::ExceptionAssertionViolated, 0, 0, NULL); + } + +private: + bool LoadDll() throw() + { + bool result = false; + + // hCrshhndlDll should not be unloaded, crash may appear even after return from main(). + // So hCrshhndlDll is not saved after construction. + HMODULE hCrshhndlDll = ::LoadLibraryW(L"crshhndl.dll"); + if (hCrshhndlDll != NULL) + { + m_InitCrashHandler = (pfnInitCrashHandler) GetProcAddress(hCrshhndlDll, "InitCrashHandler"); + m_SendReport = (pfnSendReport) GetProcAddress(hCrshhndlDll, "SendReport"); + m_IsReadyToExit = (pfnIsReadyToExit) GetProcAddress(hCrshhndlDll, "IsReadyToExit"); + m_AddUserInfoToReport = (pfnAddUserInfoToReport) GetProcAddress(hCrshhndlDll, "AddUserInfoToReport"); + m_AddFileToReport = (pfnAddFileToReport) GetProcAddress(hCrshhndlDll, "AddFileToReport"); + m_RemoveFileFromReport = (pfnRemoveFileFromReport) GetProcAddress(hCrshhndlDll, "RemoveFileFromReport"); + m_GetVersionFromApp = (pfnGetVersionFromApp) GetProcAddress(hCrshhndlDll, "GetVersionFromApp"); + m_GetVersionFromFile = (pfnGetVersionFromFile) GetProcAddress(hCrshhndlDll, "GetVersionFromFile"); + + result = m_InitCrashHandler + && m_SendReport + && m_IsReadyToExit + && m_AddUserInfoToReport + && m_AddFileToReport + && m_RemoveFileFromReport + && m_GetVersionFromApp + && m_GetVersionFromFile; + } + +#if _WIN32_WINNT >= 0x0501 /*_WIN32_WINNT_WINXP*/ + // if no crash processing was started, we need to ignore ExceptionAssertionViolated exceptions. + if (!result) + ::AddVectoredExceptionHandler(TRUE, SkipAsserts); +#endif + + return result; + } + + static LONG CALLBACK SkipAsserts(EXCEPTION_POINTERS* pExceptionInfo) + { + if (pExceptionInfo->ExceptionRecord->ExceptionCode == ExceptionAssertionViolated) + return EXCEPTION_CONTINUE_EXECUTION; + return EXCEPTION_CONTINUE_SEARCH; + } + + typedef BOOL (*pfnInitCrashHandler)(ApplicationInfo* applicationInfo, HandlerSettings* handlerSettings, BOOL ownProcess); + typedef LONG (*pfnSendReport)(EXCEPTION_POINTERS* exceptionPointers); + typedef BOOL (*pfnIsReadyToExit)(); + typedef void (*pfnAddUserInfoToReport)(LPCWSTR key, LPCWSTR value); + typedef void (*pfnAddFileToReport)(LPCWSTR path, LPCWSTR reportFileName /* = NULL */); + typedef void (*pfnRemoveFileFromReport)(LPCWSTR path); + typedef BOOL (*pfnGetVersionFromApp)(ApplicationInfo* appInfo); + typedef BOOL (*pfnGetVersionFromFile)(LPCWSTR path, ApplicationInfo* appInfo); + + pfnInitCrashHandler m_InitCrashHandler; + pfnSendReport m_SendReport; + pfnIsReadyToExit m_IsReadyToExit; + pfnAddUserInfoToReport m_AddUserInfoToReport; + pfnAddFileToReport m_AddFileToReport; + pfnRemoveFileFromReport m_RemoveFileFromReport; + pfnGetVersionFromApp m_GetVersionFromApp; + pfnGetVersionFromFile m_GetVersionFromFile; +}; + +#endif // __CRASH_HANDLER_H__ \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.rc b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.rc new file mode 100644 index 000000000..ba239e70b --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.rc @@ -0,0 +1,58 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define _WIN32_WINNT 0x0501 +#include "afxres.h" +#include "projectinfo.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian (Russia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define _WIN32_WINNT 0x0501\r\n" + "#include ""afxres.h""\r\n" + "#include ""projectinfo.h""\0" +END + +3 TEXTINCLUDE +BEGIN + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// RCDATA +// + +IDR_SENDRPT RCDATA "sendrpt.exe" +#endif // Russian (Russia) resources +///////////////////////////////////////////////////////////////////////////// + + diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj new file mode 100644 index 000000000..7fb0fb782 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj @@ -0,0 +1,307 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + Template + Win32 + + + Template + x64 + + + + {17308759-20C0-493C-8190-06224DBCFD88} + CrashHandler + Win32Proj + + + + DynamicLibrary + Static + Unicode + true + + + DynamicLibrary + Static + Unicode + true + + + DynamicLibrary + Static + Unicode + + + DynamicLibrary + Static + Unicode + + + DynamicLibrary + + + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + true + true + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + crshhndl + crshhndl + crshhndl + crshhndl + crshhndl + crshhndl + .dll + .dll + false + false + false + false + + + + Disabled + ..\gsoap-win32-2.7;..\zlib123;..\wtl\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + Level3 + EditAndContinue + + + _UNICODE;UNICODE;%(PreprocessorDefinitions) + $(OutDir);%(AdditionalIncludeDirectories) + + + version.lib;%(AdditionalDependencies) + %(AdditionalManifestDependencies) + CrashHandler.def + true + Console + + + MachineX86 + + + Adding symbols/images to store... + "%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(TargetDir)$(TargetName).pdb" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) +"%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(OutDir)crshhndl.dll" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) + + + + + + Disabled + ..\gsoap-win32-2.7;..\zlib123;..\wtl\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDebug + Use + Level3 + ProgramDatabase + + + _UNICODE;UNICODE;%(PreprocessorDefinitions) + $(OutDir);%(AdditionalIncludeDirectories) + + + version.lib;%(AdditionalDependencies) + %(AdditionalManifestDependencies) + CrashHandler.def + true + Console + + + + + Adding symbols/images to store... + "%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(TargetDir)$(TargetName).pdb" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) +"%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(OutDir)crshhndl.dll" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) + + + + + + MaxSpeed + true + ..\gsoap-win32-2.7;..\zlib123;..\wtl\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + _UNICODE;UNICODE;%(PreprocessorDefinitions) + $(OutDir);%(AdditionalIncludeDirectories) + + + version.lib;%(AdditionalDependencies) + CrashHandler.def + true + Console + true + true + + + MachineX86 + + + Adding symbols/images to store... + "%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(TargetDir)$(TargetName).pdb" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) +"%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(OutDir)crshhndl.dll" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) + + + + + + MaxSpeed + true + ..\gsoap-win32-2.7;..\zlib123;..\wtl\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + _UNICODE;UNICODE;%(PreprocessorDefinitions) + $(OutDir);%(AdditionalIncludeDirectories) + + + version.lib;%(AdditionalDependencies) + CrashHandler.def + true + Console + true + true + + + + + Adding symbols/images to store... + "%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(TargetDir)$(TargetName).pdb" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) +"%ProgramFiles%\Debugging Tools for Windows (x86)\symstore.exe" add /f "$(OutDir)crshhndl.dll" /s $(SolutionDir)..\Data\Symsrv\idolsoftware /t $(ProjectName) + + + + + + + $(OutDir);%(AdditionalIncludeDirectories) + + + + + + $(OutDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + {60557edd-7d52-4200-8884-7541105387f9} + + + + + + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj.filters b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj.filters new file mode 100644 index 000000000..953d4a934 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandler.vcxproj.filters @@ -0,0 +1,65 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/CrashHandler/CrashHandlerExport.h b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandlerExport.h new file mode 100644 index 000000000..6cf6cf5a6 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/CrashHandlerExport.h @@ -0,0 +1,41 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __CRASH_HANDLER_EXPORT_H__ +#define __CRASH_HANDLER_EXPORT_H__ + +#include "CrashHandler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL InitCrashHandler(ApplicationInfo* applicationInfo, HandlerSettings* handlerSettings, BOOL ownProcess); +BOOL IsReadyToExit(); +void AddUserInfoToReport(LPCWSTR key, LPCWSTR value); +void AddFileToReport(LPCWSTR path, LPCWSTR reportFileName /* = NULL */); +void RemoveFileFromReport(LPCWSTR path); +BOOL GetVersionFromApp(ApplicationInfo* appInfo); +BOOL GetVersionFromFile(LPCWSTR path, ApplicationInfo* appInfo); +LONG SendReport(EXCEPTION_POINTERS* exceptionPointers); +void CrashServer_SendAssertionViolated(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // __CRASH_HANDLER_EXPORT_H__ \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/CrashHandler/projectinfo.h b/ext/CrashServer/CrashHandler/CrashHandler/projectinfo.h new file mode 100644 index 000000000..26a8971ba --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/projectinfo.h @@ -0,0 +1,26 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __PROJECTINFO_H +#define __PROJECTINFO_H + +#define VERSION_INTERNALNAME_STR "crshhndl" +#define VERSION_FILEDESCRIPTION_STR "Crash handler library" + +#include + +#endif// __PROJECTINFO_H diff --git a/ext/CrashServer/CrashHandler/CrashHandler/resource.h b/ext/CrashServer/CrashHandler/CrashHandler/resource.h new file mode 100644 index 000000000..34756da03 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by CrashHandler.rc +// +#define IDR_SENDRPT 106 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1016 +#define _APS_NEXT_SYMED_VALUE 104 +#endif +#endif diff --git a/ext/CrashServer/CrashHandler/CrashHandler/stdafx.cpp b/ext/CrashServer/CrashHandler/CrashHandler/stdafx.cpp new file mode 100644 index 000000000..359df47d3 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/stdafx.cpp @@ -0,0 +1,18 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "stdafx.h" diff --git a/ext/CrashServer/CrashHandler/CrashHandler/stdafx.h b/ext/CrashServer/CrashHandler/CrashHandler/stdafx.h new file mode 100644 index 000000000..4ebeb8166 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/stdafx.h @@ -0,0 +1,32 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include "targetver.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; diff --git a/ext/CrashServer/CrashHandler/CrashHandler/targetver.h b/ext/CrashServer/CrashHandler/CrashHandler/targetver.h new file mode 100644 index 000000000..a00a2ffb0 --- /dev/null +++ b/ext/CrashServer/CrashHandler/CrashHandler/targetver.h @@ -0,0 +1,23 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#define _WIN32_WINNT 0x0501 +#define WINVER 0x0501 + + diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj new file mode 100644 index 000000000..1e1df14c2 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {EEA8E6F4-76F0-42F7-A139-725C0B368A36} + DumpUploaderServiceLib + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + $(GsoapDir);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;SOAP_DEBUG;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Level3 + EditAndContinue + + + + + Disabled + $(GsoapDir);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;SOAP_DEBUG;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + Level3 + ProgramDatabase + + + + + MinSpace + $(GsoapDir);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;SOAP_NDEBUG;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + + + + + MinSpace + $(GsoapDir);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;SOAP_NDEBUG;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj.filters b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj.filters new file mode 100644 index 000000000..92eeceda0 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderServiceLib.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {db00495d-2b06-45d8-8086-64902f518c55} + + + {9ddbc61f-814e-47cb-aff0-120a14e8e639} + + + + + Source Files + + + Source Files + + + DumpUploadService Files + + + DumpUploadService Files + + + Gsoap Files + + + + + Header Files + + + Header Files + + + DumpUploadService Files + + + DumpUploadService Files + + + DumpUploadService Files + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.cpp b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.cpp new file mode 100644 index 000000000..e630cbb95 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.cpp @@ -0,0 +1,81 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "DumpUploaderWebService.h" +#include "generated\UploaderSoap.nsmap" +#include "gsoapWinInet.h" +#include +#include +#include + +DumpUploaderWebService::DumpUploaderWebService(int responseTimeoutSec) + : UploaderSoapProxy(SOAP_ENC_MTOM|SOAP_IO_KEEPALIVE|SOAP_C_UTFSTRING/*SOAP_C_MBSTRING*/) +{ + m_serviceUrl = "https://www.crash-server.com"; + + CRegKey reg; + if (ERROR_SUCCESS == reg.Open(HKEY_LOCAL_MACHINE, _T("Software\\Idol Software\\DumpUploader"), KEY_READ)) + { + CString str; + ULONG size = 1000; + if (ERROR_SUCCESS == reg.QueryStringValue(_T("ServiceURL"), str.GetBuffer(size), &size)) + { + str.ReleaseBuffer(size-1); + m_serviceUrl = str; + } + + DWORD cfgResponseTimeoutSec = 0; + if (ERROR_SUCCESS == reg.QueryDWORDValue(_T("ResponseTimeoutSec"), cfgResponseTimeoutSec) && cfgResponseTimeoutSec != 0) + responseTimeoutSec = static_cast(cfgResponseTimeoutSec); + +#ifdef _DEBUG // soap_set_*_logfile defined only in DEBUG build of GSOAP + DWORD traceEnable = FALSE; + if (ERROR_SUCCESS == reg.QueryDWORDValue(_T("TraceEnable"), traceEnable) && traceEnable != FALSE) + { + size = 1000; + if (ERROR_SUCCESS == reg.QueryStringValue(_T("TraceFolder"), str.GetBuffer(size), &size)) + { + str.ReleaseBuffer(size-1); + soap_set_test_logfile(this, str + _T("\\_gsoap_test.log")); + soap_set_sent_logfile(this, str + _T("\\_gsoap_sent.log")); + soap_set_recv_logfile(this, str + _T("\\_gsoap_recv.log")); + } + } +#endif + } + + m_serviceUrl += "/DumpUploader.asmx"; + + soap_endpoint = m_serviceUrl.c_str(); + recv_timeout = responseTimeoutSec; + soap_register_plugin(this, wininet_plugin); +} + +std::wstring DumpUploaderWebService::GetErrorText() +{ + std::ostringstream o; + soap_stream_fault(o); + std::vector buf(o.str().size() + 1); + buf.resize(MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) o.str().c_str(), (int)o.str().size() + 1, &buf.front(), (int)buf.size())); + + return std::wstring(buf.begin(), buf.end()); +} + +void DumpUploaderWebService::SetProgressCallback(pfnProgressCallback progressCallback, LPVOID context) +{ + wininet_set_progress_callback(this, progressCallback, context); +} diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.h new file mode 100644 index 000000000..a24a2e3de --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/DumpUploaderWebService.h @@ -0,0 +1,31 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include "generated\soapUploaderSoapProxy.h" + +class DumpUploaderWebService : public UploaderSoapProxy +{ + std::string m_serviceUrl; +public: + DumpUploaderWebService(int responseTimeoutSec = 0); + std::wstring GetErrorText(); + + typedef void (*pfnProgressCallback)(BOOL send, SIZE_T bytesCount, LPVOID context); + void SetProgressCallback(pfnProgressCallback progressCallback, LPVOID context); +}; diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/DumpUploader.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/DumpUploader.h new file mode 100644 index 000000000..5500abd5c --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/DumpUploader.h @@ -0,0 +1,1225 @@ +// Reminder: Modify typemap.dat to customize the header file generated by wsdl2h +/* DumpUploader.h + Generated by wsdl2h 2.8.0 from http://localhost:59175/DumpUploader.asmx?WSDL and C:\CrashServer\Sources\ClientSide\DumpUploaderServiceLib\\typemap.dat + 2012-01-09 21:40:50 GMT + + DO NOT INCLUDE THIS FILE DIRECTLY INTO YOUR PROJECT BUILDS + USE THE soapcpp2-GENERATED SOURCE CODE FILES FOR YOUR PROJECT BUILDS + + gSOAP XML Web services tools. + Copyright (C) 2001-2010 Robert van Engelen, Genivia Inc. All Rights Reserved. + Part of this software is released under one of the following licenses: + GPL or Genivia's license for commercial use. +*/ + +/** @page page_notes Usage Notes + +NOTE: + + - Run soapcpp2 on DumpUploader.h to generate the SOAP/XML processing logic. + Use soapcpp2 option -I to specify paths for #import + To build with STL, 'stlvector.h' is imported from 'import' dir in package. + Use soapcpp2 option -i to generate improved proxy and server classes. + - Use wsdl2h options -c and -s to generate pure C code or C++ code without STL. + - Use 'typemap.dat' to control namespace bindings and type mappings. + It is strongly recommended to customize the names of the namespace prefixes + generated by wsdl2h. To do so, modify the prefix bindings in the Namespaces + section below and add the modified lines to 'typemap.dat' to rerun wsdl2h. + - Use Doxygen (www.doxygen.org) on this file to generate documentation. + - Use wsdl2h options -nname and -Nname to globally rename the prefix 'ns'. + - Use wsdl2h option -d to enable DOM support for xsd:anyType. + - Use wsdl2h option -g to auto-generate readers and writers for root elements. + - Struct/class members serialized as XML attributes are annotated with a '@'. + - Struct/class members that have a special role are annotated with a '$'. + +WARNING: + + DO NOT INCLUDE THIS FILE DIRECTLY INTO YOUR PROJECT BUILDS. + USE THE SOURCE CODE FILES GENERATED BY soapcpp2 FOR YOUR PROJECT BUILDS: + THE soapStub.h FILE CONTAINS THIS CONTENT WITHOUT ANNOTATIONS. + +LICENSE: + +@verbatim +-------------------------------------------------------------------------------- +gSOAP XML Web services tools +Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + +This software is released under one of the following two licenses: +1) GPL or 2) Genivia's license for commercial use. +-------------------------------------------------------------------------------- +1) GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +2) A commercial-use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- +@endverbatim + +*/ + + +//gsoapopt w + +/******************************************************************************\ + * * + * Definitions * + * https://www.crash-server.com/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Import * + * * +\******************************************************************************/ + + +// STL vector containers (use option -s to remove STL dependency) +#import "stlvector.h" + +/******************************************************************************\ + * * + * Schema Namespaces * + * * +\******************************************************************************/ + +// This service uses SOAP 1.2 namespaces: +//gsoap SOAP-ENV schema namespace: http://www.w3.org/2003/05/soap-envelope +//gsoap SOAP-ENC schema namespace: http://www.w3.org/2003/05/soap-encoding + +/* NOTE: + +It is strongly recommended to customize the names of the namespace prefixes +generated by wsdl2h. To do so, modify the prefix bindings below and add the +modified lines to typemap.dat to rerun wsdl2h: + +ns1 = "https://www.crash-server.com/" +ns2 = "http://microsoft.com/wsdl/types/" + +*/ + +#define SOAP_NAMESPACE_OF_ns1 "https://www.crash-server.com/" +//gsoap ns1 schema namespace: https://www.crash-server.com/ +//gsoap ns1 schema elementForm: qualified +//gsoap ns1 schema attributeForm: unqualified + +#define SOAP_NAMESPACE_OF_ns2 "http://microsoft.com/wsdl/types/" +//gsoap ns2 schema namespace: http://microsoft.com/wsdl/types/ +//gsoap ns2 schema elementForm: qualified +//gsoap ns2 schema attributeForm: unqualified + +/******************************************************************************\ + * * + * Built-in Schema Types and Top-Level Elements and Attributes * + * * +\******************************************************************************/ + + +/// Built-in type "xs:base64Binary". +#import "xop.h" + +/******************************************************************************\ + * * + * Forward Declarations * + * * +\******************************************************************************/ + + + +// Forward declaration of class ns1__ClientLib. +class ns1__ClientLib; + +// Forward declaration of class ns1__Application. +class ns1__Application; + +// Forward declaration of class ns1__Response. +class ns1__Response; + +// Forward declaration of class ns1__Solution. +class ns1__Solution; + +// Forward declaration of class _ns1__Hello. +class _ns1__Hello; + +// Forward declaration of class _ns1__HelloResponse. +class _ns1__HelloResponse; + +// Forward declaration of class _ns1__UploadMiniDump. +class _ns1__UploadMiniDump; + +// Forward declaration of class _ns1__UploadMiniDumpResponse. +class _ns1__UploadMiniDumpResponse; + +// Forward declaration of class _ns1__UploadAdditionalInfo. +class _ns1__UploadAdditionalInfo; + +// Forward declaration of class _ns1__UploadAdditionalInfoResponse. +class _ns1__UploadAdditionalInfoResponse; + +// Forward declaration of class _ns1__UploadSymbol. +class _ns1__UploadSymbol; + +// Forward declaration of class _ns1__UploadSymbolResponse. +class _ns1__UploadSymbolResponse; + +/******************************************************************************\ + * * + * Schema Types and Top-Level Elements and Attributes * + * https://www.crash-server.com/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Schema Types and Top-Level Elements and Attributes * + * http://microsoft.com/wsdl/types/ * + * * +\******************************************************************************/ + + +/// "https://www.crash-server.com/":Architecture is a simpleType restriction of xs:string. +/// Note: enum values are prefixed with 'ns1__Architecture' to avoid name clashes, please use wsdl2h option -e to omit this prefix +enum ns1__Architecture +{ + ns1__Architecture__x32, ///< xs:string value="x32" + ns1__Architecture__x64, ///< xs:string value="x64" +}; + +/// "https://www.crash-server.com/":ResponseType is a simpleType restriction of xs:string. +/// Note: enum values are prefixed with 'ns1__ResponseType' to avoid name clashes, please use wsdl2h option -e to omit this prefix +enum ns1__ResponseType +{ + ns1__ResponseType__HaveSolution, ///< xs:string value="HaveSolution" + ns1__ResponseType__NeedMiniDump, ///< xs:string value="NeedMiniDump" + ns1__ResponseType__NeedMoreInfo, ///< xs:string value="NeedMoreInfo" + ns1__ResponseType__Stop, ///< xs:string value="Stop" + ns1__ResponseType__Error, ///< xs:string value="Error" +}; + +/// "https://www.crash-server.com/":SolutionType is a simpleType restriction of xs:string. +/// Note: enum values are prefixed with 'ns1__SolutionType' to avoid name clashes, please use wsdl2h option -e to omit this prefix +enum ns1__SolutionType +{ + ns1__SolutionType__Url, ///< xs:string value="Url" + ns1__SolutionType__Exe, ///< xs:string value="Exe" +}; + +/// "https://www.crash-server.com/":AdditionalInfoType is a simpleType restriction of xs:string. +/// Note: enum values are prefixed with 'ns1__AdditionalInfoType' to avoid name clashes, please use wsdl2h option -e to omit this prefix +enum ns1__AdditionalInfoType +{ + ns1__AdditionalInfoType__None, ///< xs:string value="None" + ns1__AdditionalInfoType__FullDump, ///< xs:string value="FullDump" + ns1__AdditionalInfoType__Info, ///< xs:string value="Info" +}; + +/******************************************************************************\ + * * + * Schema Types and Top-Level Elements and Attributes * + * http://microsoft.com/wsdl/types/ * + * * +\******************************************************************************/ + + +/// "http://microsoft.com/wsdl/types/":guid is a simpleType restriction of xs:string. +/// Content pattern is "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" (note: not automatically enforced) +typedef std::wstring ns2__guid "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"; + +/******************************************************************************\ + * * + * Schema Complex Types and Top-Level Elements * + * https://www.crash-server.com/ * + * * +\******************************************************************************/ + + +/// "https://www.crash-server.com/":ClientLib is a complexType. +class ns1__ClientLib +{ public: +/// Element v1 of type xs:unsignedShort. + unsigned short v1 1; ///< Required element. +/// Element v2 of type xs:unsignedShort. + unsigned short v2 1; ///< Required element. +/// Element v3 of type xs:unsignedShort. + unsigned short v3 1; ///< Required element. +/// Element v4 of type xs:unsignedShort. + unsigned short v4 1; ///< Required element. +/// Element arch of type "https://www.crash-server.com/":Architecture. + enum ns1__Architecture arch 1; ///< Required element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + +/// "https://www.crash-server.com/":Application is a complexType. +class ns1__Application +{ public: +/// Element applicationGUID of type "http://microsoft.com/wsdl/types/":guid. + ns2__guid applicationGUID 1; ///< Required element. +/// Element v1 of type xs:unsignedShort. + unsigned short v1 1; ///< Required element. +/// Element v2 of type xs:unsignedShort. + unsigned short v2 1; ///< Required element. +/// Element v3 of type xs:unsignedShort. + unsigned short v3 1; ///< Required element. +/// Element v4 of type xs:unsignedShort. + unsigned short v4 1; ///< Required element. +/// Element hotfix of type xs:unsignedShort. + unsigned short hotfix 1; ///< Required element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + +/// "https://www.crash-server.com/":Response is a complexType. +class ns1__Response +{ public: +/// Element type of type "https://www.crash-server.com/":ResponseType. + enum ns1__ResponseType type 1; ///< Required element. +/// Element error of type xs:string. + std::wstring* error 0; ///< Optional element. +/// Element solution of type "https://www.crash-server.com/":Solution. + ns1__Solution* solution 0; ///< Optional element. +/// Element clientID of type xs:string. + std::wstring* clientID 0; ///< Optional element. +/// Element problemID of type xs:int. + int problemID 1; ///< Required element. +/// Element dumpGroupID of type xs:int. + int dumpGroupID 1; ///< Required element. +/// Element dumpID of type xs:int. + int dumpID 1; ///< Required element. +/// Element urlToProblem of type xs:string. + std::wstring* urlToProblem 0; ///< Optional element. +/// Element infoType of type "https://www.crash-server.com/":AdditionalInfoType. + enum ns1__AdditionalInfoType infoType 1; ///< Required element. +/// Element infoModule of type xs:base64Binary. + _xop__Include* infoModule 0; ///< Optional element. +/// Element infoModuleCfg of type xs:string. + std::wstring* infoModuleCfg 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + +/// "https://www.crash-server.com/":Solution is a complexType. +class ns1__Solution +{ public: +/// Element askConfirmation of type xs:boolean. + bool askConfirmation 1; ///< Required element. +/// Element type of type "https://www.crash-server.com/":SolutionType. + enum ns1__SolutionType type 1; ///< Required element. +/// Element url of type xs:string. + std::wstring* url 0; ///< Optional element. +/// Element exe of type xs:base64Binary. + _xop__Include* exe 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":Hello + +/// "https://www.crash-server.com/":Hello is a complexType. +class _ns1__Hello +{ public: +/// Element client of type "https://www.crash-server.com/":ClientLib. + ns1__ClientLib* client 0; ///< Optional element. +/// Element app of type "https://www.crash-server.com/":Application. + ns1__Application* app 0; ///< Optional element. +/// Element mainModule of type xs:string. + std::wstring* mainModule 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":HelloResponse + +/// "https://www.crash-server.com/":HelloResponse is a complexType. +class _ns1__HelloResponse +{ public: +/// Element HelloResult of type "https://www.crash-server.com/":Response. + ns1__Response* HelloResult 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":UploadMiniDump + +/// "https://www.crash-server.com/":UploadMiniDump is a complexType. +class _ns1__UploadMiniDump +{ public: +/// Element client of type "https://www.crash-server.com/":ClientLib. + ns1__ClientLib* client 0; ///< Optional element. +/// Element app of type "https://www.crash-server.com/":Application. + ns1__Application* app 0; ///< Optional element. +/// Element mainModule of type xs:string. + std::wstring* mainModule 0; ///< Optional element. +/// Element PCID of type xs:int. + int PCID 1; ///< Required element. +/// Element submitterID of type xs:int. + int submitterID 1; ///< Required element. +/// Element dump of type xs:base64Binary. + _xop__Include* dump 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":UploadMiniDumpResponse + +/// "https://www.crash-server.com/":UploadMiniDumpResponse is a complexType. +class _ns1__UploadMiniDumpResponse +{ public: +/// Element UploadMiniDumpResult of type "https://www.crash-server.com/":Response. + ns1__Response* UploadMiniDumpResult 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":UploadAdditionalInfo + +/// "https://www.crash-server.com/":UploadAdditionalInfo is a complexType. +class _ns1__UploadAdditionalInfo +{ public: +/// Element client of type "https://www.crash-server.com/":ClientLib. + ns1__ClientLib* client 0; ///< Optional element. +/// Element app of type "https://www.crash-server.com/":Application. + ns1__Application* app 0; ///< Optional element. +/// Element mainModule of type xs:string. + std::wstring* mainModule 0; ///< Optional element. +/// Element miniDumpID of type xs:int. + int miniDumpID 1; ///< Required element. +/// Element info of type xs:base64Binary. + _xop__Include* info 0; ///< Optional element. +/// Element infoType of type "https://www.crash-server.com/":AdditionalInfoType. + enum ns1__AdditionalInfoType infoType 1; ///< Required element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":UploadAdditionalInfoResponse + +/// "https://www.crash-server.com/":UploadAdditionalInfoResponse is a complexType. +class _ns1__UploadAdditionalInfoResponse +{ public: +/// Element UploadAdditionalInfoResult of type "https://www.crash-server.com/":Response. + ns1__Response* UploadAdditionalInfoResult 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":UploadSymbol + +/// "https://www.crash-server.com/":UploadSymbol is a complexType. +class _ns1__UploadSymbol +{ public: +/// Element client of type "https://www.crash-server.com/":ClientLib. + ns1__ClientLib* client 0; ///< Optional element. +/// Element app of type "https://www.crash-server.com/":Application. + ns1__Application* app 0; ///< Optional element. +/// Element publish of type xs:boolean. + bool publish 1; ///< Required element. +/// Element sym of type xs:base64Binary. + _xop__Include* sym 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + + +/// Top-level root element "https://www.crash-server.com/":UploadSymbolResponse + +/// "https://www.crash-server.com/":UploadSymbolResponse is a complexType. +class _ns1__UploadSymbolResponse +{ public: +/// Element UploadSymbolResult of type xs:string. + std::wstring* UploadSymbolResult 0; ///< Optional element. +/// A handle to the soap struct that manages this instance (automatically set) + struct soap *soap ; +}; + +/******************************************************************************\ + * * + * Schema Complex Types and Top-Level Elements * + * http://microsoft.com/wsdl/types/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Additional Top-Level Elements * + * https://www.crash-server.com/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Additional Top-Level Attributes * + * https://www.crash-server.com/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Additional Top-Level Elements * + * http://microsoft.com/wsdl/types/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Additional Top-Level Attributes * + * http://microsoft.com/wsdl/types/ * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Services * + * * +\******************************************************************************/ + + +//gsoap ns3 service name: UploaderSoap +//gsoap ns3 service type: UploaderSoap +//gsoap ns3 service port: http://localhost:59175/DumpUploader.asmx +//gsoap ns3 service namespace: https://www.crash-server.com/UploaderSoap +//gsoap ns3 service transport: http://schemas.xmlsoap.org/soap/http + +//gsoap ns4 service name: UploaderSoap12 +//gsoap ns4 service type: UploaderSoap +//gsoap ns4 service port: http://localhost:59175/DumpUploader.asmx +//gsoap ns4 service namespace: https://www.crash-server.com/UploaderSoap12 +//gsoap ns4 service transport: http://schemas.xmlsoap.org/soap/http + +/** @mainpage Service Definitions + +@section Service_bindings Service Bindings + + - @ref UploaderSoap + + - @ref UploaderSoap12 + +@section Service_more More Information + + - @ref page_notes "Usage Notes" + + - @ref page_XMLDataBinding "XML Data Binding" + + - @ref SOAP_ENV__Header "SOAP Header Content" (when applicable) + + - @ref SOAP_ENV__Detail "SOAP Fault Detail Content" (when applicable) + + +*/ + +/** + +@page UploaderSoap Binding "UploaderSoap" + +@section UploaderSoap_operations Operations of Binding "UploaderSoap" + + - @ref __ns3__Hello + + - @ref __ns3__UploadMiniDump + + - @ref __ns3__UploadAdditionalInfo + + - @ref __ns3__UploadSymbol + +@section UploaderSoap_ports Endpoints of Binding "UploaderSoap" + + - http://localhost:59175/DumpUploader.asmx + +Note: use wsdl2h option -N to change the service binding prefix name + +*/ + +/** + +@page UploaderSoap12 Binding "UploaderSoap12" + +@section UploaderSoap12_operations Operations of Binding "UploaderSoap12" + + - @ref __ns4__Hello + + - @ref __ns4__UploadMiniDump + + - @ref __ns4__UploadAdditionalInfo + + - @ref __ns4__UploadSymbol + +@section UploaderSoap12_ports Endpoints of Binding "UploaderSoap12" + + - http://localhost:59175/DumpUploader.asmx + +Note: use wsdl2h option -N to change the service binding prefix name + +*/ + +/******************************************************************************\ + * * + * Service Binding * + * UploaderSoap * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Service Operation * + * __ns3__Hello * + * * +\******************************************************************************/ + + +/// Operation "__ns3__Hello" of service binding "UploaderSoap" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/Hello" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns3__Hello( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__Hello* ns1__Hello, + // response parameters: + _ns1__HelloResponse* ns1__HelloResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns3__Hello( + struct soap *soap, + // request parameters: + _ns1__Hello* ns1__Hello, + // response parameters: + _ns1__HelloResponse* ns1__HelloResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoapProxy.h): +@code + class UploaderSoapProxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoapService.h): +@code + class UploaderSoapService; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns3 service method-style: Hello document +//gsoap ns3 service method-encoding: Hello literal +//gsoap ns3 service method-action: Hello https://www.crash-server.com/Hello +int __ns3__Hello( + _ns1__Hello* ns1__Hello, ///< Request parameter + _ns1__HelloResponse* ns1__HelloResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Operation * + * __ns3__UploadMiniDump * + * * +\******************************************************************************/ + + +/// Operation "__ns3__UploadMiniDump" of service binding "UploaderSoap" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/UploadMiniDump" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns3__UploadMiniDump( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__UploadMiniDump* ns1__UploadMiniDump, + // response parameters: + _ns1__UploadMiniDumpResponse* ns1__UploadMiniDumpResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns3__UploadMiniDump( + struct soap *soap, + // request parameters: + _ns1__UploadMiniDump* ns1__UploadMiniDump, + // response parameters: + _ns1__UploadMiniDumpResponse* ns1__UploadMiniDumpResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoapProxy.h): +@code + class UploaderSoapProxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoapService.h): +@code + class UploaderSoapService; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns3 service method-style: UploadMiniDump document +//gsoap ns3 service method-encoding: UploadMiniDump literal +//gsoap ns3 service method-action: UploadMiniDump https://www.crash-server.com/UploadMiniDump +int __ns3__UploadMiniDump( + _ns1__UploadMiniDump* ns1__UploadMiniDump, ///< Request parameter + _ns1__UploadMiniDumpResponse* ns1__UploadMiniDumpResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Operation * + * __ns3__UploadAdditionalInfo * + * * +\******************************************************************************/ + + +/// Operation "__ns3__UploadAdditionalInfo" of service binding "UploaderSoap" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/UploadAdditionalInfo" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns3__UploadAdditionalInfo( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__UploadAdditionalInfo* ns1__UploadAdditionalInfo, + // response parameters: + _ns1__UploadAdditionalInfoResponse* ns1__UploadAdditionalInfoResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns3__UploadAdditionalInfo( + struct soap *soap, + // request parameters: + _ns1__UploadAdditionalInfo* ns1__UploadAdditionalInfo, + // response parameters: + _ns1__UploadAdditionalInfoResponse* ns1__UploadAdditionalInfoResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoapProxy.h): +@code + class UploaderSoapProxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoapService.h): +@code + class UploaderSoapService; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns3 service method-style: UploadAdditionalInfo document +//gsoap ns3 service method-encoding: UploadAdditionalInfo literal +//gsoap ns3 service method-action: UploadAdditionalInfo https://www.crash-server.com/UploadAdditionalInfo +int __ns3__UploadAdditionalInfo( + _ns1__UploadAdditionalInfo* ns1__UploadAdditionalInfo, ///< Request parameter + _ns1__UploadAdditionalInfoResponse* ns1__UploadAdditionalInfoResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Operation * + * __ns3__UploadSymbol * + * * +\******************************************************************************/ + + +/// Operation "__ns3__UploadSymbol" of service binding "UploaderSoap" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/UploadSymbol" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns3__UploadSymbol( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__UploadSymbol* ns1__UploadSymbol, + // response parameters: + _ns1__UploadSymbolResponse* ns1__UploadSymbolResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns3__UploadSymbol( + struct soap *soap, + // request parameters: + _ns1__UploadSymbol* ns1__UploadSymbol, + // response parameters: + _ns1__UploadSymbolResponse* ns1__UploadSymbolResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoapProxy.h): +@code + class UploaderSoapProxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoapService.h): +@code + class UploaderSoapService; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns3 service method-style: UploadSymbol document +//gsoap ns3 service method-encoding: UploadSymbol literal +//gsoap ns3 service method-action: UploadSymbol https://www.crash-server.com/UploadSymbol +int __ns3__UploadSymbol( + _ns1__UploadSymbol* ns1__UploadSymbol, ///< Request parameter + _ns1__UploadSymbolResponse* ns1__UploadSymbolResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Binding * + * UploaderSoap12 * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Service Operation * + * __ns4__Hello * + * * +\******************************************************************************/ + + +/// Operation "__ns4__Hello" of service binding "UploaderSoap12" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/Hello" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns4__Hello( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__Hello* ns1__Hello, + // response parameters: + _ns1__HelloResponse* ns1__HelloResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns4__Hello( + struct soap *soap, + // request parameters: + _ns1__Hello* ns1__Hello, + // response parameters: + _ns1__HelloResponse* ns1__HelloResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoap12Proxy.h): +@code + class UploaderSoap12Proxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoap12Service.h): +@code + class UploaderSoap12Service; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns4 service method-style: Hello document +//gsoap ns4 service method-encoding: Hello literal +//gsoap ns4 service method-action: Hello https://www.crash-server.com/Hello +int __ns4__Hello( + _ns1__Hello* ns1__Hello, ///< Request parameter + _ns1__HelloResponse* ns1__HelloResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Operation * + * __ns4__UploadMiniDump * + * * +\******************************************************************************/ + + +/// Operation "__ns4__UploadMiniDump" of service binding "UploaderSoap12" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/UploadMiniDump" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns4__UploadMiniDump( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__UploadMiniDump* ns1__UploadMiniDump, + // response parameters: + _ns1__UploadMiniDumpResponse* ns1__UploadMiniDumpResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns4__UploadMiniDump( + struct soap *soap, + // request parameters: + _ns1__UploadMiniDump* ns1__UploadMiniDump, + // response parameters: + _ns1__UploadMiniDumpResponse* ns1__UploadMiniDumpResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoap12Proxy.h): +@code + class UploaderSoap12Proxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoap12Service.h): +@code + class UploaderSoap12Service; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns4 service method-style: UploadMiniDump document +//gsoap ns4 service method-encoding: UploadMiniDump literal +//gsoap ns4 service method-action: UploadMiniDump https://www.crash-server.com/UploadMiniDump +int __ns4__UploadMiniDump( + _ns1__UploadMiniDump* ns1__UploadMiniDump, ///< Request parameter + _ns1__UploadMiniDumpResponse* ns1__UploadMiniDumpResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Operation * + * __ns4__UploadAdditionalInfo * + * * +\******************************************************************************/ + + +/// Operation "__ns4__UploadAdditionalInfo" of service binding "UploaderSoap12" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/UploadAdditionalInfo" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns4__UploadAdditionalInfo( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__UploadAdditionalInfo* ns1__UploadAdditionalInfo, + // response parameters: + _ns1__UploadAdditionalInfoResponse* ns1__UploadAdditionalInfoResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns4__UploadAdditionalInfo( + struct soap *soap, + // request parameters: + _ns1__UploadAdditionalInfo* ns1__UploadAdditionalInfo, + // response parameters: + _ns1__UploadAdditionalInfoResponse* ns1__UploadAdditionalInfoResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoap12Proxy.h): +@code + class UploaderSoap12Proxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoap12Service.h): +@code + class UploaderSoap12Service; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns4 service method-style: UploadAdditionalInfo document +//gsoap ns4 service method-encoding: UploadAdditionalInfo literal +//gsoap ns4 service method-action: UploadAdditionalInfo https://www.crash-server.com/UploadAdditionalInfo +int __ns4__UploadAdditionalInfo( + _ns1__UploadAdditionalInfo* ns1__UploadAdditionalInfo, ///< Request parameter + _ns1__UploadAdditionalInfoResponse* ns1__UploadAdditionalInfoResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * Service Operation * + * __ns4__UploadSymbol * + * * +\******************************************************************************/ + + +/// Operation "__ns4__UploadSymbol" of service binding "UploaderSoap12" + +/** + +Operation details: + + + - SOAP document/literal style messaging + + - SOAP action="https://www.crash-server.com/UploadSymbol" + +C stub function (defined in soapClient.c[pp] generated by soapcpp2): +@code + int soap_call___ns4__UploadSymbol( + struct soap *soap, + NULL, // char *endpoint = NULL selects default endpoint for this operation + NULL, // char *action = NULL selects default action for this operation + // request parameters: + _ns1__UploadSymbol* ns1__UploadSymbol, + // response parameters: + _ns1__UploadSymbolResponse* ns1__UploadSymbolResponse + ); +@endcode + +C server function (called from the service dispatcher defined in soapServer.c[pp]): +@code + int __ns4__UploadSymbol( + struct soap *soap, + // request parameters: + _ns1__UploadSymbol* ns1__UploadSymbol, + // response parameters: + _ns1__UploadSymbolResponse* ns1__UploadSymbolResponse + ); +@endcode + +C++ proxy class (defined in soapUploaderSoap12Proxy.h): +@code + class UploaderSoap12Proxy; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use proxy classes; + +C++ service class (defined in soapUploaderSoap12Service.h): +@code + class UploaderSoap12Service; +@endcode +Important: use soapcpp2 option '-i' to generate greatly improved and easy-to-use service classes; + +*/ + +//gsoap ns4 service method-style: UploadSymbol document +//gsoap ns4 service method-encoding: UploadSymbol literal +//gsoap ns4 service method-action: UploadSymbol https://www.crash-server.com/UploadSymbol +int __ns4__UploadSymbol( + _ns1__UploadSymbol* ns1__UploadSymbol, ///< Request parameter + _ns1__UploadSymbolResponse* ns1__UploadSymbolResponse ///< Response parameter +); + +/******************************************************************************\ + * * + * XML Data Binding * + * * +\******************************************************************************/ + + +/** + +@page page_XMLDataBinding XML Data Binding + +SOAP/XML services use data bindings contractually bound by WSDL and auto- +generated by wsdl2h and soapcpp2 (see Service Bindings). Plain data bindings +are adopted from XML schemas as part of the WSDL types section or when running +wsdl2h on a set of schemas to produce non-SOAP-based XML data bindings. + +The following readers and writers are C/C++ data type (de)serializers auto- +generated by wsdl2h and soapcpp2. Run soapcpp2 on this file to generate the +(de)serialization code, which is stored in soapC.c[pp]. Include "soapH.h" in +your code to import these data type and function declarations. Only use the +soapcpp2-generated files in your project build. Do not include the wsdl2h- +generated .h file in your code. + +XML content can be retrieved from: + - a file descriptor, using soap->recvfd = fd + - a socket, using soap->socket = ... + - a C++ stream, using soap->is = ... + - a buffer, using the soap->frecv() callback + +XML content can be stored to: + - a file descriptor, using soap->sendfd = fd + - a socket, using soap->socket = ... + - a C++ stream, using soap->os = ... + - a buffer, using the soap->fsend() callback + + +@section ns1 Top-level root elements of schema "https://www.crash-server.com/" + + - @ref _ns1__Hello + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__Hello(struct soap*, _ns1__Hello*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__Hello(struct soap*, _ns1__Hello*); + @endcode + + - @ref _ns1__HelloResponse + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__HelloResponse(struct soap*, _ns1__HelloResponse*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__HelloResponse(struct soap*, _ns1__HelloResponse*); + @endcode + + - @ref _ns1__UploadMiniDump + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__UploadMiniDump(struct soap*, _ns1__UploadMiniDump*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__UploadMiniDump(struct soap*, _ns1__UploadMiniDump*); + @endcode + + - @ref _ns1__UploadMiniDumpResponse + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__UploadMiniDumpResponse(struct soap*, _ns1__UploadMiniDumpResponse*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__UploadMiniDumpResponse(struct soap*, _ns1__UploadMiniDumpResponse*); + @endcode + + - @ref _ns1__UploadAdditionalInfo + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__UploadAdditionalInfo(struct soap*, _ns1__UploadAdditionalInfo*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__UploadAdditionalInfo(struct soap*, _ns1__UploadAdditionalInfo*); + @endcode + + - @ref _ns1__UploadAdditionalInfoResponse + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__UploadAdditionalInfoResponse(struct soap*, _ns1__UploadAdditionalInfoResponse*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__UploadAdditionalInfoResponse(struct soap*, _ns1__UploadAdditionalInfoResponse*); + @endcode + + - @ref _ns1__UploadSymbol + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__UploadSymbol(struct soap*, _ns1__UploadSymbol*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__UploadSymbol(struct soap*, _ns1__UploadSymbol*); + @endcode + + - @ref _ns1__UploadSymbolResponse + @code + // Reader (returns SOAP_OK on success): + soap_read__ns1__UploadSymbolResponse(struct soap*, _ns1__UploadSymbolResponse*); + // Writer (returns SOAP_OK on success): + soap_write__ns1__UploadSymbolResponse(struct soap*, _ns1__UploadSymbolResponse*); + @endcode + +@section ns2 Top-level root elements of schema "http://microsoft.com/wsdl/types/" + +*/ + +/* End of DumpUploader.h */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap.nsmap b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap.nsmap new file mode 100644 index 000000000..5c12fa6c5 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap.nsmap @@ -0,0 +1,15 @@ + +#include "soapH.h" +SOAP_NMAC struct Namespace namespaces[] = +{ + {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://www.w3.org/2003/05/soap-envelope", NULL}, + {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://www.w3.org/2003/05/soap-encoding", NULL}, + {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, + {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, + {"xop", "http://www.w3.org/2004/08/xop/include", NULL, NULL}, + {"ns2", "http://microsoft.com/wsdl/types/", NULL, NULL}, + {"ns3", "https://www.crash-server.com/UploaderSoap", NULL, NULL}, + {"ns1", "https://www.crash-server.com/", NULL, NULL}, + {"ns4", "https://www.crash-server.com/UploaderSoap12", NULL, NULL}, + {NULL, NULL, NULL, NULL} +}; diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap12.nsmap b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap12.nsmap new file mode 100644 index 000000000..5c12fa6c5 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/UploaderSoap12.nsmap @@ -0,0 +1,15 @@ + +#include "soapH.h" +SOAP_NMAC struct Namespace namespaces[] = +{ + {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://www.w3.org/2003/05/soap-envelope", NULL}, + {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://www.w3.org/2003/05/soap-encoding", NULL}, + {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, + {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, + {"xop", "http://www.w3.org/2004/08/xop/include", NULL, NULL}, + {"ns2", "http://microsoft.com/wsdl/types/", NULL, NULL}, + {"ns3", "https://www.crash-server.com/UploaderSoap", NULL, NULL}, + {"ns1", "https://www.crash-server.com/", NULL, NULL}, + {"ns4", "https://www.crash-server.com/UploaderSoap12", NULL, NULL}, + {NULL, NULL, NULL, NULL} +}; diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapC.cpp b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapC.cpp new file mode 100644 index 000000000..5dc96179b --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapC.cpp @@ -0,0 +1,6279 @@ +/* soapC.cpp + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#if defined(__BORLANDC__) +#pragma option push -w-8060 +#pragma option push -w-8004 +#endif + +#include "soapH.h" + +SOAP_SOURCE_STAMP("@(#) soapC.cpp ver 2.8.0 2012-01-09 21:40:51 GMT") + + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_serializeheader(struct soap *soap) +{ + if (soap->header) + soap_serialize_SOAP_ENV__Header(soap, soap->header); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_putheader(struct soap *soap) +{ + if (soap->header) + { soap->part = SOAP_IN_HEADER; + if (soap_out_SOAP_ENV__Header(soap, "SOAP-ENV:Header", 0, soap->header, NULL)) + return soap->error; + soap->part = SOAP_END_HEADER; + } + return SOAP_OK; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_getheader(struct soap *soap) +{ + soap->part = SOAP_IN_HEADER; + soap->header = soap_in_SOAP_ENV__Header(soap, "SOAP-ENV:Header", NULL, NULL); + soap->part = SOAP_END_HEADER; + return soap->header == NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_header(struct soap *soap) +{ + if (!soap->header) + { if ((soap->header = soap_new_SOAP_ENV__Header(soap, -1))) + soap_default_SOAP_ENV__Header(soap, soap->header); + } +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_fault(struct soap *soap) +{ + if (!soap->fault) + { soap->fault = soap_new_SOAP_ENV__Fault(soap, -1); + if (!soap->fault) + return; + soap_default_SOAP_ENV__Fault(soap, soap->fault); + } + if (soap->version == 2 && !soap->fault->SOAP_ENV__Code) + { soap->fault->SOAP_ENV__Code = soap_new_SOAP_ENV__Code(soap, -1); + soap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code); + } + if (soap->version == 2 && !soap->fault->SOAP_ENV__Reason) + { soap->fault->SOAP_ENV__Reason = soap_new_SOAP_ENV__Reason(soap, -1); + soap_default_SOAP_ENV__Reason(soap, soap->fault->SOAP_ENV__Reason); + } +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serializefault(struct soap *soap) +{ + soap_fault(soap); + if (soap->fault) + soap_serialize_SOAP_ENV__Fault(soap, soap->fault); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_putfault(struct soap *soap) +{ + if (soap->fault) + return soap_put_SOAP_ENV__Fault(soap, soap->fault, "SOAP-ENV:Fault", NULL); + return SOAP_OK; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_getfault(struct soap *soap) +{ + return (soap->fault = soap_get_SOAP_ENV__Fault(soap, NULL, "SOAP-ENV:Fault", NULL)) == NULL; +} + +SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultcode(struct soap *soap) +{ + soap_fault(soap); + if (soap->version == 2) + return (const char**)&soap->fault->SOAP_ENV__Code->SOAP_ENV__Value; + return (const char**)&soap->fault->faultcode; +} + +SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultsubcode(struct soap *soap) +{ + soap_fault(soap); + if (soap->version == 2) + { if (!soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode) + { soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode = soap_new_SOAP_ENV__Code(soap, -1); + soap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode); + } + return (const char**)&soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode->SOAP_ENV__Value; + } + return (const char**)&soap->fault->faultcode; +} + +SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultstring(struct soap *soap) +{ + soap_fault(soap); + if (soap->version == 2) + return (const char**)&soap->fault->SOAP_ENV__Reason->SOAP_ENV__Text; + return (const char**)&soap->fault->faultstring; +} + +SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultdetail(struct soap *soap) +{ + soap_fault(soap); + if (soap->version == 1) + { if (!soap->fault->detail) + { soap->fault->detail = (struct SOAP_ENV__Detail*)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail)); + soap_default_SOAP_ENV__Detail(soap, soap->fault->detail); + } + return (const char**)&soap->fault->detail->__any; + } + if (!soap->fault->SOAP_ENV__Detail) + { soap->fault->SOAP_ENV__Detail = soap_new_SOAP_ENV__Detail(soap, -1); + soap_default_SOAP_ENV__Detail(soap, soap->fault->SOAP_ENV__Detail); + } + return (const char**)&soap->fault->SOAP_ENV__Detail->__any; +} + +#endif + +#ifndef WITH_NOIDREF +SOAP_FMAC3 int SOAP_FMAC4 soap_getindependent(struct soap *soap) +{ + int t; + if (soap->version == 1) + { for (;;) + { if (!soap_getelement(soap, &t)) + if (soap->error || soap_ignore_element(soap)) + break; + } + } + if (soap->error == SOAP_NO_TAG || soap->error == SOAP_EOF) + soap->error = SOAP_OK; + return soap->error; +} +#endif + +#ifndef WITH_NOIDREF + +#ifdef __cplusplus +extern "C" { +#endif +SOAP_FMAC3 void * SOAP_FMAC4 soap_getelement(struct soap *soap, int *type) +{ + if (soap_peek_element(soap)) + return NULL; + if (!*soap->id || !(*type = soap_lookup_type(soap, soap->id))) + *type = soap_lookup_type(soap, soap->href); + switch (*type) + { + case SOAP_TYPE_byte: + return soap_in_byte(soap, NULL, NULL, "xsd:byte"); + case SOAP_TYPE_short: + return soap_in_short(soap, NULL, NULL, "xsd:short"); + case SOAP_TYPE_int: + return soap_in_int(soap, NULL, NULL, "xsd:int"); + case SOAP_TYPE_unsignedByte: + return soap_in_unsignedByte(soap, NULL, NULL, "xsd:unsignedByte"); + case SOAP_TYPE_unsignedShort: + return soap_in_unsignedShort(soap, NULL, NULL, "xsd:unsignedShort"); + case SOAP_TYPE_unsignedInt: + return soap_in_unsignedInt(soap, NULL, NULL, "xsd:unsignedInt"); + case SOAP_TYPE_bool: + return soap_in_bool(soap, NULL, NULL, "xsd:boolean"); + case SOAP_TYPE_ns1__AdditionalInfoType: + return soap_in_ns1__AdditionalInfoType(soap, NULL, NULL, "ns1:AdditionalInfoType"); + case SOAP_TYPE_ns1__SolutionType: + return soap_in_ns1__SolutionType(soap, NULL, NULL, "ns1:SolutionType"); + case SOAP_TYPE_ns1__ResponseType: + return soap_in_ns1__ResponseType(soap, NULL, NULL, "ns1:ResponseType"); + case SOAP_TYPE_ns1__Architecture: + return soap_in_ns1__Architecture(soap, NULL, NULL, "ns1:Architecture"); + case SOAP_TYPE_ns2__guid: + return soap_in_ns2__guid(soap, NULL, NULL, "ns2:guid"); + case SOAP_TYPE_std__wstring: + return soap_in_std__wstring(soap, NULL, NULL, "xsd:string"); + case SOAP_TYPE_ns1__Solution: + return soap_in_ns1__Solution(soap, NULL, NULL, "ns1:Solution"); + case SOAP_TYPE_ns1__Response: + return soap_in_ns1__Response(soap, NULL, NULL, "ns1:Response"); + case SOAP_TYPE_ns1__Application: + return soap_in_ns1__Application(soap, NULL, NULL, "ns1:Application"); + case SOAP_TYPE_ns1__ClientLib: + return soap_in_ns1__ClientLib(soap, NULL, NULL, "ns1:ClientLib"); + case SOAP_TYPE_PointerTo_ns1__UploadSymbolResponse: + return soap_in_PointerTo_ns1__UploadSymbolResponse(soap, NULL, NULL, "ns1:UploadSymbolResponse"); + case SOAP_TYPE_PointerTo_ns1__UploadSymbol: + return soap_in_PointerTo_ns1__UploadSymbol(soap, NULL, NULL, "ns1:UploadSymbol"); + case SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfoResponse: + return soap_in_PointerTo_ns1__UploadAdditionalInfoResponse(soap, NULL, NULL, "ns1:UploadAdditionalInfoResponse"); + case SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfo: + return soap_in_PointerTo_ns1__UploadAdditionalInfo(soap, NULL, NULL, "ns1:UploadAdditionalInfo"); + case SOAP_TYPE_PointerTo_ns1__UploadMiniDumpResponse: + return soap_in_PointerTo_ns1__UploadMiniDumpResponse(soap, NULL, NULL, "ns1:UploadMiniDumpResponse"); + case SOAP_TYPE_PointerTo_ns1__UploadMiniDump: + return soap_in_PointerTo_ns1__UploadMiniDump(soap, NULL, NULL, "ns1:UploadMiniDump"); + case SOAP_TYPE_PointerTo_ns1__HelloResponse: + return soap_in_PointerTo_ns1__HelloResponse(soap, NULL, NULL, "ns1:HelloResponse"); + case SOAP_TYPE_PointerTo_ns1__Hello: + return soap_in_PointerTo_ns1__Hello(soap, NULL, NULL, "ns1:Hello"); + case SOAP_TYPE_PointerTons1__Response: + return soap_in_PointerTons1__Response(soap, NULL, NULL, "ns1:Response"); + case SOAP_TYPE_PointerTons1__Application: + return soap_in_PointerTons1__Application(soap, NULL, NULL, "ns1:Application"); + case SOAP_TYPE_PointerTons1__ClientLib: + return soap_in_PointerTons1__ClientLib(soap, NULL, NULL, "ns1:ClientLib"); + case SOAP_TYPE_PointerTo_xop__Include: + return soap_in_PointerTo_xop__Include(soap, NULL, NULL, "xop:Include"); + case SOAP_TYPE_PointerTons1__Solution: + return soap_in_PointerTons1__Solution(soap, NULL, NULL, "ns1:Solution"); + case SOAP_TYPE_PointerTostd__wstring: + return soap_in_PointerTostd__wstring(soap, NULL, NULL, "xsd:string"); + case SOAP_TYPE_PointerTounsignedByte: + return soap_in_PointerTounsignedByte(soap, NULL, NULL, "xsd:unsignedByte"); + case SOAP_TYPE__QName: + { char **s; + s = soap_in__QName(soap, NULL, NULL, "xsd:QName"); + return s ? *s : NULL; + } + case SOAP_TYPE_string: + { char **s; + s = soap_in_string(soap, NULL, NULL, "xsd:string"); + return s ? *s : NULL; + } + default: + { const char *t = soap->type; + if (!*t) + t = soap->tag; + if (!soap_match_tag(soap, t, "ns2:guid")) + { *type = SOAP_TYPE_ns2__guid; + return soap_in_ns2__guid(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:string")) + { *type = SOAP_TYPE_std__wstring; + return soap_in_std__wstring(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:Solution")) + { *type = SOAP_TYPE_ns1__Solution; + return soap_in_ns1__Solution(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:Response")) + { *type = SOAP_TYPE_ns1__Response; + return soap_in_ns1__Response(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:Application")) + { *type = SOAP_TYPE_ns1__Application; + return soap_in_ns1__Application(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:ClientLib")) + { *type = SOAP_TYPE_ns1__ClientLib; + return soap_in_ns1__ClientLib(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:byte")) + { *type = SOAP_TYPE_byte; + return soap_in_byte(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:short")) + { *type = SOAP_TYPE_short; + return soap_in_short(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:int")) + { *type = SOAP_TYPE_int; + return soap_in_int(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:unsignedByte")) + { *type = SOAP_TYPE_unsignedByte; + return soap_in_unsignedByte(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:unsignedShort")) + { *type = SOAP_TYPE_unsignedShort; + return soap_in_unsignedShort(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:unsignedInt")) + { *type = SOAP_TYPE_unsignedInt; + return soap_in_unsignedInt(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:boolean")) + { *type = SOAP_TYPE_bool; + return soap_in_bool(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:AdditionalInfoType")) + { *type = SOAP_TYPE_ns1__AdditionalInfoType; + return soap_in_ns1__AdditionalInfoType(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:SolutionType")) + { *type = SOAP_TYPE_ns1__SolutionType; + return soap_in_ns1__SolutionType(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:ResponseType")) + { *type = SOAP_TYPE_ns1__ResponseType; + return soap_in_ns1__ResponseType(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:Architecture")) + { *type = SOAP_TYPE_ns1__Architecture; + return soap_in_ns1__Architecture(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xsd:QName")) + { char **s; + *type = SOAP_TYPE__QName; + s = soap_in__QName(soap, NULL, NULL, NULL); + return s ? *s : NULL; + } + if (!soap_match_tag(soap, t, "xsd:string")) + { char **s; + *type = SOAP_TYPE_string; + s = soap_in_string(soap, NULL, NULL, NULL); + return s ? *s : NULL; + } + t = soap->tag; + if (!soap_match_tag(soap, t, "ns1:UploadSymbolResponse")) + { *type = SOAP_TYPE__ns1__UploadSymbolResponse; + return soap_in__ns1__UploadSymbolResponse(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:UploadSymbol")) + { *type = SOAP_TYPE__ns1__UploadSymbol; + return soap_in__ns1__UploadSymbol(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:UploadAdditionalInfoResponse")) + { *type = SOAP_TYPE__ns1__UploadAdditionalInfoResponse; + return soap_in__ns1__UploadAdditionalInfoResponse(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:UploadAdditionalInfo")) + { *type = SOAP_TYPE__ns1__UploadAdditionalInfo; + return soap_in__ns1__UploadAdditionalInfo(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:UploadMiniDumpResponse")) + { *type = SOAP_TYPE__ns1__UploadMiniDumpResponse; + return soap_in__ns1__UploadMiniDumpResponse(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:UploadMiniDump")) + { *type = SOAP_TYPE__ns1__UploadMiniDump; + return soap_in__ns1__UploadMiniDump(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:HelloResponse")) + { *type = SOAP_TYPE__ns1__HelloResponse; + return soap_in__ns1__HelloResponse(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "ns1:Hello")) + { *type = SOAP_TYPE__ns1__Hello; + return soap_in__ns1__Hello(soap, NULL, NULL, NULL); + } + if (!soap_match_tag(soap, t, "xop:Include")) + { *type = SOAP_TYPE__xop__Include; + return soap_in__xop__Include(soap, NULL, NULL, NULL); + } + } + } + soap->error = SOAP_TAG_MISMATCH; + return NULL; +} + +#ifdef __cplusplus +} +#endif +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_ignore_element(struct soap *soap) +{ + if (!soap_peek_element(soap)) + { int t; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unexpected element '%s' in input (level=%u, %d)\n", soap->tag, soap->level, soap->body)); + if (soap->mustUnderstand && !soap->other) + return soap->error = SOAP_MUSTUNDERSTAND; + if (((soap->mode & SOAP_XML_STRICT) && soap->part != SOAP_IN_HEADER) || !soap_match_tag(soap, soap->tag, "SOAP-ENV:")) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "REJECTING element '%s'\n", soap->tag)); + return soap->error = SOAP_TAG_MISMATCH; + } + if (!*soap->id || !soap_getelement(soap, &t)) + { soap->peeked = 0; + if (soap->fignore) + soap->error = soap->fignore(soap, soap->tag); + else + soap->error = SOAP_OK; + DBGLOG(TEST, if (!soap->error) SOAP_MESSAGE(fdebug, "IGNORING element '%s'\n", soap->tag)); + if (!soap->error && soap->body) + { soap->level++; + while (!soap_ignore_element(soap)) + ; + if (soap->error == SOAP_NO_TAG) + soap->error = soap_element_end_in(soap, NULL); + } + } + } + return soap->error; +} + +#ifndef WITH_NOIDREF +SOAP_FMAC3 int SOAP_FMAC4 soap_putindependent(struct soap *soap) +{ + int i; + struct soap_plist *pp; + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & (SOAP_XML_TREE | SOAP_XML_GRAPH))) + for (i = 0; i < SOAP_PTRHASH; i++) + for (pp = soap->pht[i]; pp; pp = pp->next) + if (pp->mark1 == 2 || pp->mark2 == 2) + if (soap_putelement(soap, pp->ptr, "id", pp->id, pp->type)) + return soap->error; + return SOAP_OK; +} +#endif + +#ifndef WITH_NOIDREF + +#ifdef __cplusplus +extern "C" { +#endif +SOAP_FMAC3 int SOAP_FMAC4 soap_putelement(struct soap *soap, const void *ptr, const char *tag, int id, int type) +{ + switch (type) + { + case SOAP_TYPE_byte: + return soap_out_byte(soap, tag, id, (const char *)ptr, "xsd:byte"); + case SOAP_TYPE_short: + return soap_out_short(soap, tag, id, (const short *)ptr, "xsd:short"); + case SOAP_TYPE_int: + return soap_out_int(soap, tag, id, (const int *)ptr, "xsd:int"); + case SOAP_TYPE_unsignedByte: + return soap_out_unsignedByte(soap, tag, id, (const unsigned char *)ptr, "xsd:unsignedByte"); + case SOAP_TYPE_unsignedShort: + return soap_out_unsignedShort(soap, tag, id, (const unsigned short *)ptr, "xsd:unsignedShort"); + case SOAP_TYPE_unsignedInt: + return soap_out_unsignedInt(soap, tag, id, (const unsigned int *)ptr, "xsd:unsignedInt"); + case SOAP_TYPE_bool: + return soap_out_bool(soap, tag, id, (const bool *)ptr, "xsd:boolean"); + case SOAP_TYPE_ns1__AdditionalInfoType: + return soap_out_ns1__AdditionalInfoType(soap, tag, id, (const enum ns1__AdditionalInfoType *)ptr, "ns1:AdditionalInfoType"); + case SOAP_TYPE_ns1__SolutionType: + return soap_out_ns1__SolutionType(soap, tag, id, (const enum ns1__SolutionType *)ptr, "ns1:SolutionType"); + case SOAP_TYPE_ns1__ResponseType: + return soap_out_ns1__ResponseType(soap, tag, id, (const enum ns1__ResponseType *)ptr, "ns1:ResponseType"); + case SOAP_TYPE_ns1__Architecture: + return soap_out_ns1__Architecture(soap, tag, id, (const enum ns1__Architecture *)ptr, "ns1:Architecture"); + case SOAP_TYPE_ns2__guid: + return soap_out_ns2__guid(soap, tag, id, (const std::wstring *)ptr, "ns2:guid"); + case SOAP_TYPE_std__wstring: + return soap_out_std__wstring(soap, tag, id, (const std::wstring *)ptr, "xsd:string"); + case SOAP_TYPE__ns1__UploadSymbolResponse: + return ((_ns1__UploadSymbolResponse *)ptr)->soap_out(soap, "ns1:UploadSymbolResponse", id, NULL); + case SOAP_TYPE__ns1__UploadSymbol: + return ((_ns1__UploadSymbol *)ptr)->soap_out(soap, "ns1:UploadSymbol", id, NULL); + case SOAP_TYPE__ns1__UploadAdditionalInfoResponse: + return ((_ns1__UploadAdditionalInfoResponse *)ptr)->soap_out(soap, "ns1:UploadAdditionalInfoResponse", id, NULL); + case SOAP_TYPE__ns1__UploadAdditionalInfo: + return ((_ns1__UploadAdditionalInfo *)ptr)->soap_out(soap, "ns1:UploadAdditionalInfo", id, NULL); + case SOAP_TYPE__ns1__UploadMiniDumpResponse: + return ((_ns1__UploadMiniDumpResponse *)ptr)->soap_out(soap, "ns1:UploadMiniDumpResponse", id, NULL); + case SOAP_TYPE__ns1__UploadMiniDump: + return ((_ns1__UploadMiniDump *)ptr)->soap_out(soap, "ns1:UploadMiniDump", id, NULL); + case SOAP_TYPE__ns1__HelloResponse: + return ((_ns1__HelloResponse *)ptr)->soap_out(soap, "ns1:HelloResponse", id, NULL); + case SOAP_TYPE__ns1__Hello: + return ((_ns1__Hello *)ptr)->soap_out(soap, "ns1:Hello", id, NULL); + case SOAP_TYPE_ns1__Solution: + return ((ns1__Solution *)ptr)->soap_out(soap, tag, id, "ns1:Solution"); + case SOAP_TYPE_ns1__Response: + return ((ns1__Response *)ptr)->soap_out(soap, tag, id, "ns1:Response"); + case SOAP_TYPE_ns1__Application: + return ((ns1__Application *)ptr)->soap_out(soap, tag, id, "ns1:Application"); + case SOAP_TYPE_ns1__ClientLib: + return ((ns1__ClientLib *)ptr)->soap_out(soap, tag, id, "ns1:ClientLib"); + case SOAP_TYPE__xop__Include: + return soap_out__xop__Include(soap, "xop:Include", id, (const struct _xop__Include *)ptr, NULL); + case SOAP_TYPE_PointerTo_ns1__UploadSymbolResponse: + return soap_out_PointerTo_ns1__UploadSymbolResponse(soap, tag, id, (_ns1__UploadSymbolResponse *const*)ptr, "ns1:UploadSymbolResponse"); + case SOAP_TYPE_PointerTo_ns1__UploadSymbol: + return soap_out_PointerTo_ns1__UploadSymbol(soap, tag, id, (_ns1__UploadSymbol *const*)ptr, "ns1:UploadSymbol"); + case SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfoResponse: + return soap_out_PointerTo_ns1__UploadAdditionalInfoResponse(soap, tag, id, (_ns1__UploadAdditionalInfoResponse *const*)ptr, "ns1:UploadAdditionalInfoResponse"); + case SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfo: + return soap_out_PointerTo_ns1__UploadAdditionalInfo(soap, tag, id, (_ns1__UploadAdditionalInfo *const*)ptr, "ns1:UploadAdditionalInfo"); + case SOAP_TYPE_PointerTo_ns1__UploadMiniDumpResponse: + return soap_out_PointerTo_ns1__UploadMiniDumpResponse(soap, tag, id, (_ns1__UploadMiniDumpResponse *const*)ptr, "ns1:UploadMiniDumpResponse"); + case SOAP_TYPE_PointerTo_ns1__UploadMiniDump: + return soap_out_PointerTo_ns1__UploadMiniDump(soap, tag, id, (_ns1__UploadMiniDump *const*)ptr, "ns1:UploadMiniDump"); + case SOAP_TYPE_PointerTo_ns1__HelloResponse: + return soap_out_PointerTo_ns1__HelloResponse(soap, tag, id, (_ns1__HelloResponse *const*)ptr, "ns1:HelloResponse"); + case SOAP_TYPE_PointerTo_ns1__Hello: + return soap_out_PointerTo_ns1__Hello(soap, tag, id, (_ns1__Hello *const*)ptr, "ns1:Hello"); + case SOAP_TYPE_PointerTons1__Response: + return soap_out_PointerTons1__Response(soap, tag, id, (ns1__Response *const*)ptr, "ns1:Response"); + case SOAP_TYPE_PointerTons1__Application: + return soap_out_PointerTons1__Application(soap, tag, id, (ns1__Application *const*)ptr, "ns1:Application"); + case SOAP_TYPE_PointerTons1__ClientLib: + return soap_out_PointerTons1__ClientLib(soap, tag, id, (ns1__ClientLib *const*)ptr, "ns1:ClientLib"); + case SOAP_TYPE_PointerTo_xop__Include: + return soap_out_PointerTo_xop__Include(soap, tag, id, (struct _xop__Include *const*)ptr, "xop:Include"); + case SOAP_TYPE_PointerTons1__Solution: + return soap_out_PointerTons1__Solution(soap, tag, id, (ns1__Solution *const*)ptr, "ns1:Solution"); + case SOAP_TYPE_PointerTostd__wstring: + return soap_out_PointerTostd__wstring(soap, tag, id, (std::wstring *const*)ptr, "xsd:string"); + case SOAP_TYPE_PointerTounsignedByte: + return soap_out_PointerTounsignedByte(soap, tag, id, (unsigned char *const*)ptr, "xsd:unsignedByte"); + case SOAP_TYPE__QName: + return soap_out_string(soap, tag, id, (char*const*)&ptr, "xsd:QName"); + case SOAP_TYPE_string: + return soap_out_string(soap, tag, id, (char*const*)&ptr, "xsd:string"); + } + return SOAP_OK; +} + +#ifdef __cplusplus +} +#endif +#endif + +#ifndef WITH_NOIDREF + +#ifdef __cplusplus +extern "C" { +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap *soap, const void *ptr, int type) +{ + (void)soap; (void)ptr; (void)type; /* appease -Wall -Werror */ + switch (type) + { + case SOAP_TYPE_ns2__guid: + soap_serialize_ns2__guid(soap, (const std::wstring *)ptr); + break; + case SOAP_TYPE_std__wstring: + soap_serialize_std__wstring(soap, (const std::wstring *)ptr); + break; + case SOAP_TYPE__ns1__UploadSymbolResponse: + ((_ns1__UploadSymbolResponse *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__UploadSymbol: + ((_ns1__UploadSymbol *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__UploadAdditionalInfoResponse: + ((_ns1__UploadAdditionalInfoResponse *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__UploadAdditionalInfo: + ((_ns1__UploadAdditionalInfo *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__UploadMiniDumpResponse: + ((_ns1__UploadMiniDumpResponse *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__UploadMiniDump: + ((_ns1__UploadMiniDump *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__HelloResponse: + ((_ns1__HelloResponse *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE__ns1__Hello: + ((_ns1__Hello *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE_ns1__Solution: + ((ns1__Solution *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE_ns1__Response: + ((ns1__Response *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE_ns1__Application: + ((ns1__Application *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE_ns1__ClientLib: + ((ns1__ClientLib *)ptr)->soap_serialize(soap); + break; + case SOAP_TYPE___ns4__UploadSymbol: + soap_serialize___ns4__UploadSymbol(soap, (const struct __ns4__UploadSymbol *)ptr); + break; + case SOAP_TYPE___ns4__UploadAdditionalInfo: + soap_serialize___ns4__UploadAdditionalInfo(soap, (const struct __ns4__UploadAdditionalInfo *)ptr); + break; + case SOAP_TYPE___ns4__UploadMiniDump: + soap_serialize___ns4__UploadMiniDump(soap, (const struct __ns4__UploadMiniDump *)ptr); + break; + case SOAP_TYPE___ns4__Hello: + soap_serialize___ns4__Hello(soap, (const struct __ns4__Hello *)ptr); + break; + case SOAP_TYPE___ns3__UploadSymbol: + soap_serialize___ns3__UploadSymbol(soap, (const struct __ns3__UploadSymbol *)ptr); + break; + case SOAP_TYPE___ns3__UploadAdditionalInfo: + soap_serialize___ns3__UploadAdditionalInfo(soap, (const struct __ns3__UploadAdditionalInfo *)ptr); + break; + case SOAP_TYPE___ns3__UploadMiniDump: + soap_serialize___ns3__UploadMiniDump(soap, (const struct __ns3__UploadMiniDump *)ptr); + break; + case SOAP_TYPE___ns3__Hello: + soap_serialize___ns3__Hello(soap, (const struct __ns3__Hello *)ptr); + break; + case SOAP_TYPE__xop__Include: + soap_serialize__xop__Include(soap, (const struct _xop__Include *)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__UploadSymbolResponse: + soap_serialize_PointerTo_ns1__UploadSymbolResponse(soap, (_ns1__UploadSymbolResponse *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__UploadSymbol: + soap_serialize_PointerTo_ns1__UploadSymbol(soap, (_ns1__UploadSymbol *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfoResponse: + soap_serialize_PointerTo_ns1__UploadAdditionalInfoResponse(soap, (_ns1__UploadAdditionalInfoResponse *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfo: + soap_serialize_PointerTo_ns1__UploadAdditionalInfo(soap, (_ns1__UploadAdditionalInfo *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__UploadMiniDumpResponse: + soap_serialize_PointerTo_ns1__UploadMiniDumpResponse(soap, (_ns1__UploadMiniDumpResponse *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__UploadMiniDump: + soap_serialize_PointerTo_ns1__UploadMiniDump(soap, (_ns1__UploadMiniDump *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__HelloResponse: + soap_serialize_PointerTo_ns1__HelloResponse(soap, (_ns1__HelloResponse *const*)ptr); + break; + case SOAP_TYPE_PointerTo_ns1__Hello: + soap_serialize_PointerTo_ns1__Hello(soap, (_ns1__Hello *const*)ptr); + break; + case SOAP_TYPE_PointerTons1__Response: + soap_serialize_PointerTons1__Response(soap, (ns1__Response *const*)ptr); + break; + case SOAP_TYPE_PointerTons1__Application: + soap_serialize_PointerTons1__Application(soap, (ns1__Application *const*)ptr); + break; + case SOAP_TYPE_PointerTons1__ClientLib: + soap_serialize_PointerTons1__ClientLib(soap, (ns1__ClientLib *const*)ptr); + break; + case SOAP_TYPE_PointerTo_xop__Include: + soap_serialize_PointerTo_xop__Include(soap, (struct _xop__Include *const*)ptr); + break; + case SOAP_TYPE_PointerTons1__Solution: + soap_serialize_PointerTons1__Solution(soap, (ns1__Solution *const*)ptr); + break; + case SOAP_TYPE_PointerTostd__wstring: + soap_serialize_PointerTostd__wstring(soap, (std::wstring *const*)ptr); + break; + case SOAP_TYPE_PointerTounsignedByte: + soap_serialize_PointerTounsignedByte(soap, (unsigned char *const*)ptr); + break; + case SOAP_TYPE__QName: + soap_serialize_string(soap, (char*const*)&ptr); + break; + case SOAP_TYPE_string: + soap_serialize_string(soap, (char*const*)&ptr); + break; + } +} + +#ifdef __cplusplus +} +#endif +#endif + +SOAP_FMAC3 void * SOAP_FMAC4 soap_instantiate(struct soap *soap, int t, const char *type, const char *arrayType, size_t *n) +{ + switch (t) + { + case SOAP_TYPE__xop__Include: + return (void*)soap_instantiate__xop__Include(soap, -1, type, arrayType, n); + case SOAP_TYPE_std__wstring: + return (void*)soap_instantiate_std__wstring(soap, -1, type, arrayType, n); + case SOAP_TYPE_ns1__ClientLib: + return (void*)soap_instantiate_ns1__ClientLib(soap, -1, type, arrayType, n); + case SOAP_TYPE_ns1__Application: + return (void*)soap_instantiate_ns1__Application(soap, -1, type, arrayType, n); + case SOAP_TYPE_ns1__Response: + return (void*)soap_instantiate_ns1__Response(soap, -1, type, arrayType, n); + case SOAP_TYPE_ns1__Solution: + return (void*)soap_instantiate_ns1__Solution(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__Hello: + return (void*)soap_instantiate__ns1__Hello(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__HelloResponse: + return (void*)soap_instantiate__ns1__HelloResponse(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__UploadMiniDump: + return (void*)soap_instantiate__ns1__UploadMiniDump(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__UploadMiniDumpResponse: + return (void*)soap_instantiate__ns1__UploadMiniDumpResponse(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__UploadAdditionalInfo: + return (void*)soap_instantiate__ns1__UploadAdditionalInfo(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__UploadAdditionalInfoResponse: + return (void*)soap_instantiate__ns1__UploadAdditionalInfoResponse(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__UploadSymbol: + return (void*)soap_instantiate__ns1__UploadSymbol(soap, -1, type, arrayType, n); + case SOAP_TYPE__ns1__UploadSymbolResponse: + return (void*)soap_instantiate__ns1__UploadSymbolResponse(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns3__Hello: + return (void*)soap_instantiate___ns3__Hello(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns3__UploadMiniDump: + return (void*)soap_instantiate___ns3__UploadMiniDump(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns3__UploadAdditionalInfo: + return (void*)soap_instantiate___ns3__UploadAdditionalInfo(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns3__UploadSymbol: + return (void*)soap_instantiate___ns3__UploadSymbol(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns4__Hello: + return (void*)soap_instantiate___ns4__Hello(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns4__UploadMiniDump: + return (void*)soap_instantiate___ns4__UploadMiniDump(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns4__UploadAdditionalInfo: + return (void*)soap_instantiate___ns4__UploadAdditionalInfo(soap, -1, type, arrayType, n); + case SOAP_TYPE___ns4__UploadSymbol: + return (void*)soap_instantiate___ns4__UploadSymbol(soap, -1, type, arrayType, n); +#ifndef WITH_NOGLOBAL + case SOAP_TYPE_SOAP_ENV__Header: + return (void*)soap_instantiate_SOAP_ENV__Header(soap, -1, type, arrayType, n); +#endif +#ifndef WITH_NOGLOBAL + case SOAP_TYPE_SOAP_ENV__Code: + return (void*)soap_instantiate_SOAP_ENV__Code(soap, -1, type, arrayType, n); +#endif +#ifndef WITH_NOGLOBAL + case SOAP_TYPE_SOAP_ENV__Detail: + return (void*)soap_instantiate_SOAP_ENV__Detail(soap, -1, type, arrayType, n); +#endif +#ifndef WITH_NOGLOBAL + case SOAP_TYPE_SOAP_ENV__Reason: + return (void*)soap_instantiate_SOAP_ENV__Reason(soap, -1, type, arrayType, n); +#endif +#ifndef WITH_NOGLOBAL + case SOAP_TYPE_SOAP_ENV__Fault: + return (void*)soap_instantiate_SOAP_ENV__Fault(soap, -1, type, arrayType, n); +#endif + case SOAP_TYPE_ns2__guid: + return (void*)soap_instantiate_ns2__guid(soap, -1, type, arrayType, n); + } + return NULL; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_fdelete(struct soap_clist *p) +{ switch (p->type) + { + case SOAP_TYPE__xop__Include: + if (p->size < 0) + SOAP_DELETE((struct _xop__Include*)p->ptr); + else + SOAP_DELETE_ARRAY((struct _xop__Include*)p->ptr); + break; + case SOAP_TYPE_std__wstring: + if (p->size < 0) + SOAP_DELETE((std::wstring*)p->ptr); + else + SOAP_DELETE_ARRAY((std::wstring*)p->ptr); + break; + case SOAP_TYPE_ns1__ClientLib: + if (p->size < 0) + SOAP_DELETE((ns1__ClientLib*)p->ptr); + else + SOAP_DELETE_ARRAY((ns1__ClientLib*)p->ptr); + break; + case SOAP_TYPE_ns1__Application: + if (p->size < 0) + SOAP_DELETE((ns1__Application*)p->ptr); + else + SOAP_DELETE_ARRAY((ns1__Application*)p->ptr); + break; + case SOAP_TYPE_ns1__Response: + if (p->size < 0) + SOAP_DELETE((ns1__Response*)p->ptr); + else + SOAP_DELETE_ARRAY((ns1__Response*)p->ptr); + break; + case SOAP_TYPE_ns1__Solution: + if (p->size < 0) + SOAP_DELETE((ns1__Solution*)p->ptr); + else + SOAP_DELETE_ARRAY((ns1__Solution*)p->ptr); + break; + case SOAP_TYPE__ns1__Hello: + if (p->size < 0) + SOAP_DELETE((_ns1__Hello*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__Hello*)p->ptr); + break; + case SOAP_TYPE__ns1__HelloResponse: + if (p->size < 0) + SOAP_DELETE((_ns1__HelloResponse*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__HelloResponse*)p->ptr); + break; + case SOAP_TYPE__ns1__UploadMiniDump: + if (p->size < 0) + SOAP_DELETE((_ns1__UploadMiniDump*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__UploadMiniDump*)p->ptr); + break; + case SOAP_TYPE__ns1__UploadMiniDumpResponse: + if (p->size < 0) + SOAP_DELETE((_ns1__UploadMiniDumpResponse*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__UploadMiniDumpResponse*)p->ptr); + break; + case SOAP_TYPE__ns1__UploadAdditionalInfo: + if (p->size < 0) + SOAP_DELETE((_ns1__UploadAdditionalInfo*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__UploadAdditionalInfo*)p->ptr); + break; + case SOAP_TYPE__ns1__UploadAdditionalInfoResponse: + if (p->size < 0) + SOAP_DELETE((_ns1__UploadAdditionalInfoResponse*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__UploadAdditionalInfoResponse*)p->ptr); + break; + case SOAP_TYPE__ns1__UploadSymbol: + if (p->size < 0) + SOAP_DELETE((_ns1__UploadSymbol*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__UploadSymbol*)p->ptr); + break; + case SOAP_TYPE__ns1__UploadSymbolResponse: + if (p->size < 0) + SOAP_DELETE((_ns1__UploadSymbolResponse*)p->ptr); + else + SOAP_DELETE_ARRAY((_ns1__UploadSymbolResponse*)p->ptr); + break; + case SOAP_TYPE___ns3__Hello: + if (p->size < 0) + SOAP_DELETE((struct __ns3__Hello*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns3__Hello*)p->ptr); + break; + case SOAP_TYPE___ns3__UploadMiniDump: + if (p->size < 0) + SOAP_DELETE((struct __ns3__UploadMiniDump*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns3__UploadMiniDump*)p->ptr); + break; + case SOAP_TYPE___ns3__UploadAdditionalInfo: + if (p->size < 0) + SOAP_DELETE((struct __ns3__UploadAdditionalInfo*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns3__UploadAdditionalInfo*)p->ptr); + break; + case SOAP_TYPE___ns3__UploadSymbol: + if (p->size < 0) + SOAP_DELETE((struct __ns3__UploadSymbol*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns3__UploadSymbol*)p->ptr); + break; + case SOAP_TYPE___ns4__Hello: + if (p->size < 0) + SOAP_DELETE((struct __ns4__Hello*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns4__Hello*)p->ptr); + break; + case SOAP_TYPE___ns4__UploadMiniDump: + if (p->size < 0) + SOAP_DELETE((struct __ns4__UploadMiniDump*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns4__UploadMiniDump*)p->ptr); + break; + case SOAP_TYPE___ns4__UploadAdditionalInfo: + if (p->size < 0) + SOAP_DELETE((struct __ns4__UploadAdditionalInfo*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns4__UploadAdditionalInfo*)p->ptr); + break; + case SOAP_TYPE___ns4__UploadSymbol: + if (p->size < 0) + SOAP_DELETE((struct __ns4__UploadSymbol*)p->ptr); + else + SOAP_DELETE_ARRAY((struct __ns4__UploadSymbol*)p->ptr); + break; + case SOAP_TYPE_SOAP_ENV__Header: + if (p->size < 0) + SOAP_DELETE((struct SOAP_ENV__Header*)p->ptr); + else + SOAP_DELETE_ARRAY((struct SOAP_ENV__Header*)p->ptr); + break; + case SOAP_TYPE_SOAP_ENV__Code: + if (p->size < 0) + SOAP_DELETE((struct SOAP_ENV__Code*)p->ptr); + else + SOAP_DELETE_ARRAY((struct SOAP_ENV__Code*)p->ptr); + break; + case SOAP_TYPE_SOAP_ENV__Detail: + if (p->size < 0) + SOAP_DELETE((struct SOAP_ENV__Detail*)p->ptr); + else + SOAP_DELETE_ARRAY((struct SOAP_ENV__Detail*)p->ptr); + break; + case SOAP_TYPE_SOAP_ENV__Reason: + if (p->size < 0) + SOAP_DELETE((struct SOAP_ENV__Reason*)p->ptr); + else + SOAP_DELETE_ARRAY((struct SOAP_ENV__Reason*)p->ptr); + break; + case SOAP_TYPE_SOAP_ENV__Fault: + if (p->size < 0) + SOAP_DELETE((struct SOAP_ENV__Fault*)p->ptr); + else + SOAP_DELETE_ARRAY((struct SOAP_ENV__Fault*)p->ptr); + break; + case SOAP_TYPE_ns2__guid: + if (p->size < 0) + SOAP_DELETE((std::wstring*)p->ptr); + else + SOAP_DELETE_ARRAY((std::wstring*)p->ptr); + break; + default: return SOAP_ERR; + } + return SOAP_OK; +} + +SOAP_FMAC3 void* SOAP_FMAC4 soap_class_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, const char *type, const char *arrayType) +{ return soap_id_enter(soap, id, p, t, n, 0, type, arrayType, soap_instantiate); +} + +SOAP_FMAC3 void* SOAP_FMAC4 soap_container_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st, int tt, size_t n, unsigned int k) +{ return soap_id_forward(soap, href, p, len, st, tt, n, k, soap_container_insert); +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_container_insert(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +#ifdef WIN32 +#pragma warning(push) +#pragma warning(disable:4065) +#endif +{ + (void)soap; (void)st; (void)p; (void)len; (void)q; (void)n; /* appease -Wall -Werror */ + switch (tt) + { + default: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not insert type=%d in %d\n", st, tt)); + } +#ifdef WIN32 +#pragma warning(pop) +#endif +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_byte(struct soap *soap, char *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_byte + *a = SOAP_DEFAULT_byte; +#else + *a = (char)0; +#endif +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_byte(struct soap *soap, const char *tag, int id, const char *a, const char *type) +{ + return soap_outbyte(soap, tag, id, a, type, SOAP_TYPE_byte); +} + +SOAP_FMAC3 char * SOAP_FMAC4 soap_in_byte(struct soap *soap, const char *tag, char *a, const char *type) +{ char *p; + p = soap_inbyte(soap, tag, a, type, SOAP_TYPE_byte); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_byte(struct soap *soap, const char *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_byte); + if (soap_out_byte(soap, tag?tag:"byte", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 char * SOAP_FMAC4 soap_get_byte(struct soap *soap, char *p, const char *tag, const char *type) +{ + if ((p = soap_in_byte(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_short(struct soap *soap, short *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_short + *a = SOAP_DEFAULT_short; +#else + *a = (short)0; +#endif +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_short(struct soap *soap, const char *tag, int id, const short *a, const char *type) +{ + return soap_outshort(soap, tag, id, a, type, SOAP_TYPE_short); +} + +SOAP_FMAC3 short * SOAP_FMAC4 soap_in_short(struct soap *soap, const char *tag, short *a, const char *type) +{ short *p; + p = soap_inshort(soap, tag, a, type, SOAP_TYPE_short); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_short(struct soap *soap, const short *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_short); + if (soap_out_short(soap, tag?tag:"short", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 short * SOAP_FMAC4 soap_get_short(struct soap *soap, short *p, const char *tag, const char *type) +{ + if ((p = soap_in_short(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_int(struct soap *soap, int *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_int + *a = SOAP_DEFAULT_int; +#else + *a = (int)0; +#endif +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_int(struct soap *soap, const char *tag, int id, const int *a, const char *type) +{ + return soap_outint(soap, tag, id, a, type, SOAP_TYPE_int); +} + +SOAP_FMAC3 int * SOAP_FMAC4 soap_in_int(struct soap *soap, const char *tag, int *a, const char *type) +{ int *p; + p = soap_inint(soap, tag, a, type, SOAP_TYPE_int); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_int(struct soap *soap, const int *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_int); + if (soap_out_int(soap, tag?tag:"int", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 int * SOAP_FMAC4 soap_get_int(struct soap *soap, int *p, const char *tag, const char *type) +{ + if ((p = soap_in_int(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_unsignedByte(struct soap *soap, unsigned char *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_unsignedByte + *a = SOAP_DEFAULT_unsignedByte; +#else + *a = (unsigned char)0; +#endif +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_unsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *a, const char *type) +{ + return soap_outunsignedByte(soap, tag, id, a, type, SOAP_TYPE_unsignedByte); +} + +SOAP_FMAC3 unsigned char * SOAP_FMAC4 soap_in_unsignedByte(struct soap *soap, const char *tag, unsigned char *a, const char *type) +{ unsigned char *p; + p = soap_inunsignedByte(soap, tag, a, type, SOAP_TYPE_unsignedByte); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_unsignedByte(struct soap *soap, const unsigned char *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_unsignedByte); + if (soap_out_unsignedByte(soap, tag?tag:"unsignedByte", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 unsigned char * SOAP_FMAC4 soap_get_unsignedByte(struct soap *soap, unsigned char *p, const char *tag, const char *type) +{ + if ((p = soap_in_unsignedByte(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_unsignedShort(struct soap *soap, unsigned short *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_unsignedShort + *a = SOAP_DEFAULT_unsignedShort; +#else + *a = (unsigned short)0; +#endif +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_unsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *a, const char *type) +{ + return soap_outunsignedShort(soap, tag, id, a, type, SOAP_TYPE_unsignedShort); +} + +SOAP_FMAC3 unsigned short * SOAP_FMAC4 soap_in_unsignedShort(struct soap *soap, const char *tag, unsigned short *a, const char *type) +{ unsigned short *p; + p = soap_inunsignedShort(soap, tag, a, type, SOAP_TYPE_unsignedShort); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_unsignedShort(struct soap *soap, const unsigned short *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_unsignedShort); + if (soap_out_unsignedShort(soap, tag?tag:"unsignedShort", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 unsigned short * SOAP_FMAC4 soap_get_unsignedShort(struct soap *soap, unsigned short *p, const char *tag, const char *type) +{ + if ((p = soap_in_unsignedShort(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_unsignedInt(struct soap *soap, unsigned int *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_unsignedInt + *a = SOAP_DEFAULT_unsignedInt; +#else + *a = (unsigned int)0; +#endif +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_unsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *a, const char *type) +{ + return soap_outunsignedInt(soap, tag, id, a, type, SOAP_TYPE_unsignedInt); +} + +SOAP_FMAC3 unsigned int * SOAP_FMAC4 soap_in_unsignedInt(struct soap *soap, const char *tag, unsigned int *a, const char *type) +{ unsigned int *p; + p = soap_inunsignedInt(soap, tag, a, type, SOAP_TYPE_unsignedInt); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_unsignedInt(struct soap *soap, const unsigned int *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_unsignedInt); + if (soap_out_unsignedInt(soap, tag?tag:"unsignedInt", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 unsigned int * SOAP_FMAC4 soap_get_unsignedInt(struct soap *soap, unsigned int *p, const char *tag, const char *type) +{ + if ((p = soap_in_unsignedInt(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_bool(struct soap *soap, bool *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_bool + *a = SOAP_DEFAULT_bool; +#else + *a = (bool)0; +#endif +} + +static const struct soap_code_map soap_codes_bool[] = +{ { (long)false, "false" }, + { (long)true, "true" }, + { 0, NULL } +}; + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_bool2s(struct soap *soap, bool n) +{ + (void)soap; /* appease -Wall -Werror */ +return soap_code_str(soap_codes_bool, n!=0); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_bool(struct soap *soap, const char *tag, int id, const bool *a, const char *type) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_bool), type) || soap_send(soap, soap_bool2s(soap, *a))) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2bool(struct soap *soap, const char *s, bool *a) +{ + const struct soap_code_map *map; + if (!s) + return soap->error; + map = soap_code(soap_codes_bool, s); + if (map) + *a = (bool)(map->code != 0); + else + { long n; + if (soap_s2long(soap, s, &n) || n < 0 || n > 1) + return soap->error = SOAP_TYPE; + *a = (bool)(n != 0); + } + return SOAP_OK; +} + +SOAP_FMAC3 bool * SOAP_FMAC4 soap_in_bool(struct soap *soap, const char *tag, bool *a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + if (*soap->type && soap_match_tag(soap, soap->type, type) && soap_match_tag(soap, soap->type, ":boolean")) + { soap->error = SOAP_TYPE; + return NULL; + } + a = (bool *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_bool, sizeof(bool), 0, NULL, NULL, NULL); + if (!a) + return NULL; + if (soap->body && !*soap->href) + { if (!a || soap_s2bool(soap, soap_value(soap), a) || soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (bool *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_bool, 0, sizeof(bool), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_bool(struct soap *soap, const bool *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_bool); + if (soap_out_bool(soap, tag?tag:"boolean", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 bool * SOAP_FMAC4 soap_get_bool(struct soap *soap, bool *p, const char *tag, const char *type) +{ + if ((p = soap_in_bool(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__AdditionalInfoType(struct soap *soap, enum ns1__AdditionalInfoType *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_ns1__AdditionalInfoType + *a = SOAP_DEFAULT_ns1__AdditionalInfoType; +#else + *a = (enum ns1__AdditionalInfoType)0; +#endif +} + +static const struct soap_code_map soap_codes_ns1__AdditionalInfoType[] = +{ { (long)ns1__AdditionalInfoType__None, "None" }, + { (long)ns1__AdditionalInfoType__FullDump, "FullDump" }, + { (long)ns1__AdditionalInfoType__Info, "Info" }, + { 0, NULL } +}; + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__AdditionalInfoType2s(struct soap *soap, enum ns1__AdditionalInfoType n) +{ const char *s = soap_code_str(soap_codes_ns1__AdditionalInfoType, (long)n); + if (s) + return s; + return soap_long2s(soap, (long)n); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__AdditionalInfoType(struct soap *soap, const char *tag, int id, const enum ns1__AdditionalInfoType *a, const char *type) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__AdditionalInfoType), type) || soap_send(soap, soap_ns1__AdditionalInfoType2s(soap, *a))) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__AdditionalInfoType(struct soap *soap, const char *s, enum ns1__AdditionalInfoType *a) +{ + const struct soap_code_map *map; + if (!s) + return soap->error; + map = soap_code(soap_codes_ns1__AdditionalInfoType, s); + if (map) + *a = (enum ns1__AdditionalInfoType)map->code; + else + { long n; + if (soap_s2long(soap, s, &n) || ((soap->mode & SOAP_XML_STRICT) && (n < 0 || n > 2))) + return soap->error = SOAP_TYPE; + *a = (enum ns1__AdditionalInfoType)n; + } + return SOAP_OK; +} + +SOAP_FMAC3 enum ns1__AdditionalInfoType * SOAP_FMAC4 soap_in_ns1__AdditionalInfoType(struct soap *soap, const char *tag, enum ns1__AdditionalInfoType *a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (enum ns1__AdditionalInfoType *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__AdditionalInfoType, sizeof(enum ns1__AdditionalInfoType), 0, NULL, NULL, NULL); + if (!a) + return NULL; + if (soap->body && !*soap->href) + { if (!a || soap_s2ns1__AdditionalInfoType(soap, soap_value(soap), a) || soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (enum ns1__AdditionalInfoType *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__AdditionalInfoType, 0, sizeof(enum ns1__AdditionalInfoType), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__AdditionalInfoType(struct soap *soap, const enum ns1__AdditionalInfoType *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__AdditionalInfoType); + if (soap_out_ns1__AdditionalInfoType(soap, tag?tag:"ns1:AdditionalInfoType", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 enum ns1__AdditionalInfoType * SOAP_FMAC4 soap_get_ns1__AdditionalInfoType(struct soap *soap, enum ns1__AdditionalInfoType *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__AdditionalInfoType(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__SolutionType(struct soap *soap, enum ns1__SolutionType *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_ns1__SolutionType + *a = SOAP_DEFAULT_ns1__SolutionType; +#else + *a = (enum ns1__SolutionType)0; +#endif +} + +static const struct soap_code_map soap_codes_ns1__SolutionType[] = +{ { (long)ns1__SolutionType__Url, "Url" }, + { (long)ns1__SolutionType__Exe, "Exe" }, + { 0, NULL } +}; + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__SolutionType2s(struct soap *soap, enum ns1__SolutionType n) +{ const char *s = soap_code_str(soap_codes_ns1__SolutionType, (long)n); + if (s) + return s; + return soap_long2s(soap, (long)n); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__SolutionType(struct soap *soap, const char *tag, int id, const enum ns1__SolutionType *a, const char *type) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__SolutionType), type) || soap_send(soap, soap_ns1__SolutionType2s(soap, *a))) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__SolutionType(struct soap *soap, const char *s, enum ns1__SolutionType *a) +{ + const struct soap_code_map *map; + if (!s) + return soap->error; + map = soap_code(soap_codes_ns1__SolutionType, s); + if (map) + *a = (enum ns1__SolutionType)map->code; + else + { long n; + if (soap_s2long(soap, s, &n) || ((soap->mode & SOAP_XML_STRICT) && (n < 0 || n > 1))) + return soap->error = SOAP_TYPE; + *a = (enum ns1__SolutionType)n; + } + return SOAP_OK; +} + +SOAP_FMAC3 enum ns1__SolutionType * SOAP_FMAC4 soap_in_ns1__SolutionType(struct soap *soap, const char *tag, enum ns1__SolutionType *a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (enum ns1__SolutionType *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__SolutionType, sizeof(enum ns1__SolutionType), 0, NULL, NULL, NULL); + if (!a) + return NULL; + if (soap->body && !*soap->href) + { if (!a || soap_s2ns1__SolutionType(soap, soap_value(soap), a) || soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (enum ns1__SolutionType *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__SolutionType, 0, sizeof(enum ns1__SolutionType), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__SolutionType(struct soap *soap, const enum ns1__SolutionType *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__SolutionType); + if (soap_out_ns1__SolutionType(soap, tag?tag:"ns1:SolutionType", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 enum ns1__SolutionType * SOAP_FMAC4 soap_get_ns1__SolutionType(struct soap *soap, enum ns1__SolutionType *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__SolutionType(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__ResponseType(struct soap *soap, enum ns1__ResponseType *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_ns1__ResponseType + *a = SOAP_DEFAULT_ns1__ResponseType; +#else + *a = (enum ns1__ResponseType)0; +#endif +} + +static const struct soap_code_map soap_codes_ns1__ResponseType[] = +{ { (long)ns1__ResponseType__HaveSolution, "HaveSolution" }, + { (long)ns1__ResponseType__NeedMiniDump, "NeedMiniDump" }, + { (long)ns1__ResponseType__NeedMoreInfo, "NeedMoreInfo" }, + { (long)ns1__ResponseType__Stop, "Stop" }, + { (long)ns1__ResponseType__Error, "Error" }, + { 0, NULL } +}; + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__ResponseType2s(struct soap *soap, enum ns1__ResponseType n) +{ const char *s = soap_code_str(soap_codes_ns1__ResponseType, (long)n); + if (s) + return s; + return soap_long2s(soap, (long)n); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__ResponseType(struct soap *soap, const char *tag, int id, const enum ns1__ResponseType *a, const char *type) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__ResponseType), type) || soap_send(soap, soap_ns1__ResponseType2s(soap, *a))) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__ResponseType(struct soap *soap, const char *s, enum ns1__ResponseType *a) +{ + const struct soap_code_map *map; + if (!s) + return soap->error; + map = soap_code(soap_codes_ns1__ResponseType, s); + if (map) + *a = (enum ns1__ResponseType)map->code; + else + { long n; + if (soap_s2long(soap, s, &n) || ((soap->mode & SOAP_XML_STRICT) && (n < 0 || n > 4))) + return soap->error = SOAP_TYPE; + *a = (enum ns1__ResponseType)n; + } + return SOAP_OK; +} + +SOAP_FMAC3 enum ns1__ResponseType * SOAP_FMAC4 soap_in_ns1__ResponseType(struct soap *soap, const char *tag, enum ns1__ResponseType *a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (enum ns1__ResponseType *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__ResponseType, sizeof(enum ns1__ResponseType), 0, NULL, NULL, NULL); + if (!a) + return NULL; + if (soap->body && !*soap->href) + { if (!a || soap_s2ns1__ResponseType(soap, soap_value(soap), a) || soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (enum ns1__ResponseType *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__ResponseType, 0, sizeof(enum ns1__ResponseType), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__ResponseType(struct soap *soap, const enum ns1__ResponseType *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__ResponseType); + if (soap_out_ns1__ResponseType(soap, tag?tag:"ns1:ResponseType", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 enum ns1__ResponseType * SOAP_FMAC4 soap_get_ns1__ResponseType(struct soap *soap, enum ns1__ResponseType *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__ResponseType(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__Architecture(struct soap *soap, enum ns1__Architecture *a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_ns1__Architecture + *a = SOAP_DEFAULT_ns1__Architecture; +#else + *a = (enum ns1__Architecture)0; +#endif +} + +static const struct soap_code_map soap_codes_ns1__Architecture[] = +{ { (long)ns1__Architecture__x32, "x32" }, + { (long)ns1__Architecture__x64, "x64" }, + { 0, NULL } +}; + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__Architecture2s(struct soap *soap, enum ns1__Architecture n) +{ const char *s = soap_code_str(soap_codes_ns1__Architecture, (long)n); + if (s) + return s; + return soap_long2s(soap, (long)n); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Architecture(struct soap *soap, const char *tag, int id, const enum ns1__Architecture *a, const char *type) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__Architecture), type) || soap_send(soap, soap_ns1__Architecture2s(soap, *a))) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__Architecture(struct soap *soap, const char *s, enum ns1__Architecture *a) +{ + const struct soap_code_map *map; + if (!s) + return soap->error; + map = soap_code(soap_codes_ns1__Architecture, s); + if (map) + *a = (enum ns1__Architecture)map->code; + else + { long n; + if (soap_s2long(soap, s, &n) || ((soap->mode & SOAP_XML_STRICT) && (n < 0 || n > 1))) + return soap->error = SOAP_TYPE; + *a = (enum ns1__Architecture)n; + } + return SOAP_OK; +} + +SOAP_FMAC3 enum ns1__Architecture * SOAP_FMAC4 soap_in_ns1__Architecture(struct soap *soap, const char *tag, enum ns1__Architecture *a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (enum ns1__Architecture *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__Architecture, sizeof(enum ns1__Architecture), 0, NULL, NULL, NULL); + if (!a) + return NULL; + if (soap->body && !*soap->href) + { if (!a || soap_s2ns1__Architecture(soap, soap_value(soap), a) || soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (enum ns1__Architecture *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__Architecture, 0, sizeof(enum ns1__Architecture), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__Architecture(struct soap *soap, const enum ns1__Architecture *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__Architecture); + if (soap_out_ns1__Architecture(soap, tag?tag:"ns1:Architecture", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 enum ns1__Architecture * SOAP_FMAC4 soap_get_ns1__Architecture(struct soap *soap, enum ns1__Architecture *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__Architecture(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns2__guid(struct soap *soap, const char *tag, int id, const std::wstring *s, const char *type) +{ + if ((soap->mode & SOAP_C_NILSTRING) && s->empty()) + return soap_element_null(soap, tag, id, type); + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, s, SOAP_TYPE_ns2__guid), type) || soap_wstring_out(soap, s->c_str(), 0) || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_in_ns2__guid(struct soap *soap, const char *tag, std::wstring *s, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!s) + s = soap_new_std__wstring(soap, -1); + if (soap->null) + if (s) + s->erase(); + if (soap->body && !*soap->href) + { wchar_t *t; + s = (std::wstring*)soap_class_id_enter(soap, soap->id, s, SOAP_TYPE_ns2__guid, sizeof(std::wstring), soap->type, soap->arrayType); + if (s) + { if ((t = soap_wstring_in(soap, 1, -1, -1))) + s->assign(t); + else + return NULL; + } + } + else + s = (std::wstring*)soap_id_forward(soap, soap->href, soap_class_id_enter(soap, soap->id, s, SOAP_TYPE_ns2__guid, sizeof(std::wstring), soap->type, soap->arrayType), 0, SOAP_TYPE_ns2__guid, 0, sizeof(std::wstring), 0, soap_copy_ns2__guid); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return s; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns2__guid(struct soap *soap, const std::wstring *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns2__guid); + if (soap_out_ns2__guid(soap, tag?tag:"ns2:guid", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_get_ns2__guid(struct soap *soap, std::wstring *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns2__guid(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_std__wstring(struct soap *soap, std::wstring *p) +{ + (void)soap; /* appease -Wall -Werror */ + p->erase(); +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_std__wstring(struct soap *soap, const std::wstring *p) +{ (void)soap; (void)p; /* appease -Wall -Werror */ +} +SOAP_FMAC3 int SOAP_FMAC4 soap_out_std__wstring(struct soap *soap, const char *tag, int id, const std::wstring *s, const char *type) +{ + if ((soap->mode & SOAP_C_NILSTRING) && s->empty()) + return soap_element_null(soap, tag, id, type); + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, s, SOAP_TYPE_std__wstring), type) || soap_wstring_out(soap, s->c_str(), 0) || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_in_std__wstring(struct soap *soap, const char *tag, std::wstring *s, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!s) + s = soap_new_std__wstring(soap, -1); + if (soap->null) + if (s) + s->erase(); + if (soap->body && !*soap->href) + { wchar_t *t; + s = (std::wstring*)soap_class_id_enter(soap, soap->id, s, SOAP_TYPE_std__wstring, sizeof(std::wstring), soap->type, soap->arrayType); + if (s) + { if ((t = soap_wstring_in(soap, 1, -1, -1))) + s->assign(t); + else + return NULL; + } + } + else + s = (std::wstring*)soap_id_forward(soap, soap->href, soap_class_id_enter(soap, soap->id, s, SOAP_TYPE_std__wstring, sizeof(std::wstring), soap->type, soap->arrayType), 0, SOAP_TYPE_std__wstring, 0, sizeof(std::wstring), 0, soap_copy_std__wstring); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return s; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_std__wstring(struct soap *soap, const std::wstring *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_std__wstring); + if (soap_out_std__wstring(soap, tag?tag:"string", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_get_std__wstring(struct soap *soap, std::wstring *p, const char *tag, const char *type) +{ + if ((p = soap_in_std__wstring(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 std::wstring * SOAP_FMAC2 soap_instantiate_std__wstring(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_std__wstring(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_std__wstring, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(std::wstring); + if (size) + *size = sizeof(std::wstring); + } + else + { cp->ptr = (void*)SOAP_NEW(std::wstring[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(std::wstring); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (std::wstring*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_std__wstring(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying std::wstring %p -> %p\n", q, p)); + *(std::wstring*)p = *(std::wstring*)q; +} + +void _ns1__UploadSymbolResponse::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__UploadSymbolResponse::UploadSymbolResult = NULL; + /* transient soap skipped */ +} + +void _ns1__UploadSymbolResponse::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTostd__wstring(soap, &this->_ns1__UploadSymbolResponse::UploadSymbolResult); + /* transient soap skipped */ +} + +int _ns1__UploadSymbolResponse::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__UploadSymbolResponse(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadSymbolResponse(struct soap *soap, const char *tag, int id, const _ns1__UploadSymbolResponse *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__UploadSymbolResponse), type)) + return soap->error; + if (a->UploadSymbolResult) + soap_element_result(soap, "ns1:UploadSymbolResult"); + if (soap_out_PointerTostd__wstring(soap, "ns1:UploadSymbolResult", -1, &(a->_ns1__UploadSymbolResponse::UploadSymbolResult), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__UploadSymbolResponse::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__UploadSymbolResponse(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__UploadSymbolResponse * SOAP_FMAC4 soap_in__ns1__UploadSymbolResponse(struct soap *soap, const char *tag, _ns1__UploadSymbolResponse *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__UploadSymbolResponse *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__UploadSymbolResponse, sizeof(_ns1__UploadSymbolResponse), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__UploadSymbolResponse) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__UploadSymbolResponse *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_UploadSymbolResult1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_UploadSymbolResult1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:UploadSymbolResult", &(a->_ns1__UploadSymbolResponse::UploadSymbolResult), "xsd:string")) + { soap_flag_UploadSymbolResult1--; + continue; + } + /* transient soap skipped */ + soap_check_result(soap, "ns1:UploadSymbolResult"); + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__UploadSymbolResponse *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__UploadSymbolResponse, 0, sizeof(_ns1__UploadSymbolResponse), 0, soap_copy__ns1__UploadSymbolResponse); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +int _ns1__UploadSymbolResponse::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__UploadSymbolResponse); + if (this->soap_out(soap, tag?tag:"ns1:UploadSymbolResponse", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__UploadSymbolResponse::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__UploadSymbolResponse(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__UploadSymbolResponse * SOAP_FMAC4 soap_get__ns1__UploadSymbolResponse(struct soap *soap, _ns1__UploadSymbolResponse *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__UploadSymbolResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__UploadSymbolResponse * SOAP_FMAC2 soap_instantiate__ns1__UploadSymbolResponse(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__UploadSymbolResponse(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__UploadSymbolResponse, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadSymbolResponse); + if (size) + *size = sizeof(_ns1__UploadSymbolResponse); + ((_ns1__UploadSymbolResponse*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadSymbolResponse[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__UploadSymbolResponse); + for (int i = 0; i < n; i++) + ((_ns1__UploadSymbolResponse*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__UploadSymbolResponse*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadSymbolResponse(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__UploadSymbolResponse %p -> %p\n", q, p)); + *(_ns1__UploadSymbolResponse*)p = *(_ns1__UploadSymbolResponse*)q; +} + +void _ns1__UploadSymbol::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__UploadSymbol::client = NULL; + this->_ns1__UploadSymbol::app = NULL; + soap_default_bool(soap, &this->_ns1__UploadSymbol::publish); + this->_ns1__UploadSymbol::sym = NULL; + /* transient soap skipped */ +} + +void _ns1__UploadSymbol::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__ClientLib(soap, &this->_ns1__UploadSymbol::client); + soap_serialize_PointerTons1__Application(soap, &this->_ns1__UploadSymbol::app); + soap_serialize_PointerTo_xop__Include(soap, &this->_ns1__UploadSymbol::sym); + /* transient soap skipped */ +} + +int _ns1__UploadSymbol::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__UploadSymbol(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadSymbol(struct soap *soap, const char *tag, int id, const _ns1__UploadSymbol *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__UploadSymbol), type)) + return soap->error; + if (soap_out_PointerTons1__ClientLib(soap, "ns1:client", -1, &(a->_ns1__UploadSymbol::client), "")) + return soap->error; + if (soap_out_PointerTons1__Application(soap, "ns1:app", -1, &(a->_ns1__UploadSymbol::app), "")) + return soap->error; + if (soap_out_bool(soap, "ns1:publish", -1, &(a->_ns1__UploadSymbol::publish), "")) + return soap->error; + if (soap_out_PointerTo_xop__Include(soap, "ns1:sym", -1, &(a->_ns1__UploadSymbol::sym), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__UploadSymbol::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__UploadSymbol(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__UploadSymbol * SOAP_FMAC4 soap_in__ns1__UploadSymbol(struct soap *soap, const char *tag, _ns1__UploadSymbol *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__UploadSymbol *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__UploadSymbol, sizeof(_ns1__UploadSymbol), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__UploadSymbol) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__UploadSymbol *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_client1 = 1; + size_t soap_flag_app1 = 1; + size_t soap_flag_publish1 = 1; + size_t soap_flag_sym1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_client1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__ClientLib(soap, "ns1:client", &(a->_ns1__UploadSymbol::client), "ns1:ClientLib")) + { soap_flag_client1--; + continue; + } + if (soap_flag_app1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Application(soap, "ns1:app", &(a->_ns1__UploadSymbol::app), "ns1:Application")) + { soap_flag_app1--; + continue; + } + if (soap_flag_publish1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_bool(soap, "ns1:publish", &(a->_ns1__UploadSymbol::publish), "xsd:boolean")) + { soap_flag_publish1--; + continue; + } + if (soap_flag_sym1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_xop__Include(soap, "ns1:sym", &(a->_ns1__UploadSymbol::sym), "")) + { soap_flag_sym1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__UploadSymbol *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__UploadSymbol, 0, sizeof(_ns1__UploadSymbol), 0, soap_copy__ns1__UploadSymbol); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_publish1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int _ns1__UploadSymbol::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__UploadSymbol); + if (this->soap_out(soap, tag?tag:"ns1:UploadSymbol", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__UploadSymbol::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__UploadSymbol(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__UploadSymbol * SOAP_FMAC4 soap_get__ns1__UploadSymbol(struct soap *soap, _ns1__UploadSymbol *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__UploadSymbol(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__UploadSymbol * SOAP_FMAC2 soap_instantiate__ns1__UploadSymbol(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__UploadSymbol(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__UploadSymbol, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadSymbol); + if (size) + *size = sizeof(_ns1__UploadSymbol); + ((_ns1__UploadSymbol*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadSymbol[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__UploadSymbol); + for (int i = 0; i < n; i++) + ((_ns1__UploadSymbol*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__UploadSymbol*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadSymbol(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__UploadSymbol %p -> %p\n", q, p)); + *(_ns1__UploadSymbol*)p = *(_ns1__UploadSymbol*)q; +} + +void _ns1__UploadAdditionalInfoResponse::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__UploadAdditionalInfoResponse::UploadAdditionalInfoResult = NULL; + /* transient soap skipped */ +} + +void _ns1__UploadAdditionalInfoResponse::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__Response(soap, &this->_ns1__UploadAdditionalInfoResponse::UploadAdditionalInfoResult); + /* transient soap skipped */ +} + +int _ns1__UploadAdditionalInfoResponse::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__UploadAdditionalInfoResponse(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadAdditionalInfoResponse(struct soap *soap, const char *tag, int id, const _ns1__UploadAdditionalInfoResponse *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__UploadAdditionalInfoResponse), type)) + return soap->error; + if (a->UploadAdditionalInfoResult) + soap_element_result(soap, "ns1:UploadAdditionalInfoResult"); + if (soap_out_PointerTons1__Response(soap, "ns1:UploadAdditionalInfoResult", -1, &(a->_ns1__UploadAdditionalInfoResponse::UploadAdditionalInfoResult), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__UploadAdditionalInfoResponse::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__UploadAdditionalInfoResponse(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse * SOAP_FMAC4 soap_in__ns1__UploadAdditionalInfoResponse(struct soap *soap, const char *tag, _ns1__UploadAdditionalInfoResponse *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__UploadAdditionalInfoResponse *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__UploadAdditionalInfoResponse, sizeof(_ns1__UploadAdditionalInfoResponse), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__UploadAdditionalInfoResponse) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__UploadAdditionalInfoResponse *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_UploadAdditionalInfoResult1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_UploadAdditionalInfoResult1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Response(soap, "ns1:UploadAdditionalInfoResult", &(a->_ns1__UploadAdditionalInfoResponse::UploadAdditionalInfoResult), "ns1:Response")) + { soap_flag_UploadAdditionalInfoResult1--; + continue; + } + /* transient soap skipped */ + soap_check_result(soap, "ns1:UploadAdditionalInfoResult"); + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__UploadAdditionalInfoResponse *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__UploadAdditionalInfoResponse, 0, sizeof(_ns1__UploadAdditionalInfoResponse), 0, soap_copy__ns1__UploadAdditionalInfoResponse); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +int _ns1__UploadAdditionalInfoResponse::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__UploadAdditionalInfoResponse); + if (this->soap_out(soap, tag?tag:"ns1:UploadAdditionalInfoResponse", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__UploadAdditionalInfoResponse::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__UploadAdditionalInfoResponse(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse * SOAP_FMAC4 soap_get__ns1__UploadAdditionalInfoResponse(struct soap *soap, _ns1__UploadAdditionalInfoResponse *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__UploadAdditionalInfoResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__UploadAdditionalInfoResponse * SOAP_FMAC2 soap_instantiate__ns1__UploadAdditionalInfoResponse(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__UploadAdditionalInfoResponse(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__UploadAdditionalInfoResponse, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadAdditionalInfoResponse); + if (size) + *size = sizeof(_ns1__UploadAdditionalInfoResponse); + ((_ns1__UploadAdditionalInfoResponse*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadAdditionalInfoResponse[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__UploadAdditionalInfoResponse); + for (int i = 0; i < n; i++) + ((_ns1__UploadAdditionalInfoResponse*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__UploadAdditionalInfoResponse*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadAdditionalInfoResponse(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__UploadAdditionalInfoResponse %p -> %p\n", q, p)); + *(_ns1__UploadAdditionalInfoResponse*)p = *(_ns1__UploadAdditionalInfoResponse*)q; +} + +void _ns1__UploadAdditionalInfo::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__UploadAdditionalInfo::client = NULL; + this->_ns1__UploadAdditionalInfo::app = NULL; + this->_ns1__UploadAdditionalInfo::mainModule = NULL; + soap_default_int(soap, &this->_ns1__UploadAdditionalInfo::miniDumpID); + this->_ns1__UploadAdditionalInfo::info = NULL; + soap_default_ns1__AdditionalInfoType(soap, &this->_ns1__UploadAdditionalInfo::infoType); + /* transient soap skipped */ +} + +void _ns1__UploadAdditionalInfo::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__ClientLib(soap, &this->_ns1__UploadAdditionalInfo::client); + soap_serialize_PointerTons1__Application(soap, &this->_ns1__UploadAdditionalInfo::app); + soap_serialize_PointerTostd__wstring(soap, &this->_ns1__UploadAdditionalInfo::mainModule); + soap_serialize_PointerTo_xop__Include(soap, &this->_ns1__UploadAdditionalInfo::info); + /* transient soap skipped */ +} + +int _ns1__UploadAdditionalInfo::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__UploadAdditionalInfo(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadAdditionalInfo(struct soap *soap, const char *tag, int id, const _ns1__UploadAdditionalInfo *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__UploadAdditionalInfo), type)) + return soap->error; + if (soap_out_PointerTons1__ClientLib(soap, "ns1:client", -1, &(a->_ns1__UploadAdditionalInfo::client), "")) + return soap->error; + if (soap_out_PointerTons1__Application(soap, "ns1:app", -1, &(a->_ns1__UploadAdditionalInfo::app), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:mainModule", -1, &(a->_ns1__UploadAdditionalInfo::mainModule), "")) + return soap->error; + if (soap_out_int(soap, "ns1:miniDumpID", -1, &(a->_ns1__UploadAdditionalInfo::miniDumpID), "")) + return soap->error; + if (soap_out_PointerTo_xop__Include(soap, "ns1:info", -1, &(a->_ns1__UploadAdditionalInfo::info), "")) + return soap->error; + if (soap_out_ns1__AdditionalInfoType(soap, "ns1:infoType", -1, &(a->_ns1__UploadAdditionalInfo::infoType), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__UploadAdditionalInfo::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__UploadAdditionalInfo(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfo * SOAP_FMAC4 soap_in__ns1__UploadAdditionalInfo(struct soap *soap, const char *tag, _ns1__UploadAdditionalInfo *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__UploadAdditionalInfo *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__UploadAdditionalInfo, sizeof(_ns1__UploadAdditionalInfo), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__UploadAdditionalInfo) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__UploadAdditionalInfo *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_client1 = 1; + size_t soap_flag_app1 = 1; + size_t soap_flag_mainModule1 = 1; + size_t soap_flag_miniDumpID1 = 1; + size_t soap_flag_info1 = 1; + size_t soap_flag_infoType1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_client1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__ClientLib(soap, "ns1:client", &(a->_ns1__UploadAdditionalInfo::client), "ns1:ClientLib")) + { soap_flag_client1--; + continue; + } + if (soap_flag_app1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Application(soap, "ns1:app", &(a->_ns1__UploadAdditionalInfo::app), "ns1:Application")) + { soap_flag_app1--; + continue; + } + if (soap_flag_mainModule1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:mainModule", &(a->_ns1__UploadAdditionalInfo::mainModule), "xsd:string")) + { soap_flag_mainModule1--; + continue; + } + if (soap_flag_miniDumpID1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_int(soap, "ns1:miniDumpID", &(a->_ns1__UploadAdditionalInfo::miniDumpID), "xsd:int")) + { soap_flag_miniDumpID1--; + continue; + } + if (soap_flag_info1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_xop__Include(soap, "ns1:info", &(a->_ns1__UploadAdditionalInfo::info), "")) + { soap_flag_info1--; + continue; + } + if (soap_flag_infoType1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_ns1__AdditionalInfoType(soap, "ns1:infoType", &(a->_ns1__UploadAdditionalInfo::infoType), "ns1:AdditionalInfoType")) + { soap_flag_infoType1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__UploadAdditionalInfo *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__UploadAdditionalInfo, 0, sizeof(_ns1__UploadAdditionalInfo), 0, soap_copy__ns1__UploadAdditionalInfo); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_miniDumpID1 > 0 || soap_flag_infoType1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int _ns1__UploadAdditionalInfo::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__UploadAdditionalInfo); + if (this->soap_out(soap, tag?tag:"ns1:UploadAdditionalInfo", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__UploadAdditionalInfo::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__UploadAdditionalInfo(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfo * SOAP_FMAC4 soap_get__ns1__UploadAdditionalInfo(struct soap *soap, _ns1__UploadAdditionalInfo *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__UploadAdditionalInfo(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__UploadAdditionalInfo * SOAP_FMAC2 soap_instantiate__ns1__UploadAdditionalInfo(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__UploadAdditionalInfo(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__UploadAdditionalInfo, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadAdditionalInfo); + if (size) + *size = sizeof(_ns1__UploadAdditionalInfo); + ((_ns1__UploadAdditionalInfo*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadAdditionalInfo[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__UploadAdditionalInfo); + for (int i = 0; i < n; i++) + ((_ns1__UploadAdditionalInfo*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__UploadAdditionalInfo*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadAdditionalInfo(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__UploadAdditionalInfo %p -> %p\n", q, p)); + *(_ns1__UploadAdditionalInfo*)p = *(_ns1__UploadAdditionalInfo*)q; +} + +void _ns1__UploadMiniDumpResponse::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__UploadMiniDumpResponse::UploadMiniDumpResult = NULL; + /* transient soap skipped */ +} + +void _ns1__UploadMiniDumpResponse::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__Response(soap, &this->_ns1__UploadMiniDumpResponse::UploadMiniDumpResult); + /* transient soap skipped */ +} + +int _ns1__UploadMiniDumpResponse::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__UploadMiniDumpResponse(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadMiniDumpResponse(struct soap *soap, const char *tag, int id, const _ns1__UploadMiniDumpResponse *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__UploadMiniDumpResponse), type)) + return soap->error; + if (a->UploadMiniDumpResult) + soap_element_result(soap, "ns1:UploadMiniDumpResult"); + if (soap_out_PointerTons1__Response(soap, "ns1:UploadMiniDumpResult", -1, &(a->_ns1__UploadMiniDumpResponse::UploadMiniDumpResult), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__UploadMiniDumpResponse::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__UploadMiniDumpResponse(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__UploadMiniDumpResponse * SOAP_FMAC4 soap_in__ns1__UploadMiniDumpResponse(struct soap *soap, const char *tag, _ns1__UploadMiniDumpResponse *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__UploadMiniDumpResponse *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__UploadMiniDumpResponse, sizeof(_ns1__UploadMiniDumpResponse), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__UploadMiniDumpResponse) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__UploadMiniDumpResponse *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_UploadMiniDumpResult1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_UploadMiniDumpResult1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Response(soap, "ns1:UploadMiniDumpResult", &(a->_ns1__UploadMiniDumpResponse::UploadMiniDumpResult), "ns1:Response")) + { soap_flag_UploadMiniDumpResult1--; + continue; + } + /* transient soap skipped */ + soap_check_result(soap, "ns1:UploadMiniDumpResult"); + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__UploadMiniDumpResponse *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__UploadMiniDumpResponse, 0, sizeof(_ns1__UploadMiniDumpResponse), 0, soap_copy__ns1__UploadMiniDumpResponse); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +int _ns1__UploadMiniDumpResponse::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__UploadMiniDumpResponse); + if (this->soap_out(soap, tag?tag:"ns1:UploadMiniDumpResponse", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__UploadMiniDumpResponse::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__UploadMiniDumpResponse(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__UploadMiniDumpResponse * SOAP_FMAC4 soap_get__ns1__UploadMiniDumpResponse(struct soap *soap, _ns1__UploadMiniDumpResponse *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__UploadMiniDumpResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__UploadMiniDumpResponse * SOAP_FMAC2 soap_instantiate__ns1__UploadMiniDumpResponse(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__UploadMiniDumpResponse(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__UploadMiniDumpResponse, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadMiniDumpResponse); + if (size) + *size = sizeof(_ns1__UploadMiniDumpResponse); + ((_ns1__UploadMiniDumpResponse*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadMiniDumpResponse[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__UploadMiniDumpResponse); + for (int i = 0; i < n; i++) + ((_ns1__UploadMiniDumpResponse*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__UploadMiniDumpResponse*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadMiniDumpResponse(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__UploadMiniDumpResponse %p -> %p\n", q, p)); + *(_ns1__UploadMiniDumpResponse*)p = *(_ns1__UploadMiniDumpResponse*)q; +} + +void _ns1__UploadMiniDump::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__UploadMiniDump::client = NULL; + this->_ns1__UploadMiniDump::app = NULL; + this->_ns1__UploadMiniDump::mainModule = NULL; + soap_default_int(soap, &this->_ns1__UploadMiniDump::PCID); + soap_default_int(soap, &this->_ns1__UploadMiniDump::submitterID); + this->_ns1__UploadMiniDump::dump = NULL; + /* transient soap skipped */ +} + +void _ns1__UploadMiniDump::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__ClientLib(soap, &this->_ns1__UploadMiniDump::client); + soap_serialize_PointerTons1__Application(soap, &this->_ns1__UploadMiniDump::app); + soap_serialize_PointerTostd__wstring(soap, &this->_ns1__UploadMiniDump::mainModule); + soap_serialize_PointerTo_xop__Include(soap, &this->_ns1__UploadMiniDump::dump); + /* transient soap skipped */ +} + +int _ns1__UploadMiniDump::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__UploadMiniDump(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadMiniDump(struct soap *soap, const char *tag, int id, const _ns1__UploadMiniDump *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__UploadMiniDump), type)) + return soap->error; + if (soap_out_PointerTons1__ClientLib(soap, "ns1:client", -1, &(a->_ns1__UploadMiniDump::client), "")) + return soap->error; + if (soap_out_PointerTons1__Application(soap, "ns1:app", -1, &(a->_ns1__UploadMiniDump::app), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:mainModule", -1, &(a->_ns1__UploadMiniDump::mainModule), "")) + return soap->error; + if (soap_out_int(soap, "ns1:PCID", -1, &(a->_ns1__UploadMiniDump::PCID), "")) + return soap->error; + if (soap_out_int(soap, "ns1:submitterID", -1, &(a->_ns1__UploadMiniDump::submitterID), "")) + return soap->error; + if (soap_out_PointerTo_xop__Include(soap, "ns1:dump", -1, &(a->_ns1__UploadMiniDump::dump), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__UploadMiniDump::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__UploadMiniDump(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__UploadMiniDump * SOAP_FMAC4 soap_in__ns1__UploadMiniDump(struct soap *soap, const char *tag, _ns1__UploadMiniDump *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__UploadMiniDump *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__UploadMiniDump, sizeof(_ns1__UploadMiniDump), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__UploadMiniDump) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__UploadMiniDump *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_client1 = 1; + size_t soap_flag_app1 = 1; + size_t soap_flag_mainModule1 = 1; + size_t soap_flag_PCID1 = 1; + size_t soap_flag_submitterID1 = 1; + size_t soap_flag_dump1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_client1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__ClientLib(soap, "ns1:client", &(a->_ns1__UploadMiniDump::client), "ns1:ClientLib")) + { soap_flag_client1--; + continue; + } + if (soap_flag_app1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Application(soap, "ns1:app", &(a->_ns1__UploadMiniDump::app), "ns1:Application")) + { soap_flag_app1--; + continue; + } + if (soap_flag_mainModule1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:mainModule", &(a->_ns1__UploadMiniDump::mainModule), "xsd:string")) + { soap_flag_mainModule1--; + continue; + } + if (soap_flag_PCID1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_int(soap, "ns1:PCID", &(a->_ns1__UploadMiniDump::PCID), "xsd:int")) + { soap_flag_PCID1--; + continue; + } + if (soap_flag_submitterID1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_int(soap, "ns1:submitterID", &(a->_ns1__UploadMiniDump::submitterID), "xsd:int")) + { soap_flag_submitterID1--; + continue; + } + if (soap_flag_dump1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_xop__Include(soap, "ns1:dump", &(a->_ns1__UploadMiniDump::dump), "")) + { soap_flag_dump1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__UploadMiniDump *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__UploadMiniDump, 0, sizeof(_ns1__UploadMiniDump), 0, soap_copy__ns1__UploadMiniDump); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_PCID1 > 0 || soap_flag_submitterID1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int _ns1__UploadMiniDump::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__UploadMiniDump); + if (this->soap_out(soap, tag?tag:"ns1:UploadMiniDump", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__UploadMiniDump::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__UploadMiniDump(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__UploadMiniDump * SOAP_FMAC4 soap_get__ns1__UploadMiniDump(struct soap *soap, _ns1__UploadMiniDump *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__UploadMiniDump(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__UploadMiniDump * SOAP_FMAC2 soap_instantiate__ns1__UploadMiniDump(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__UploadMiniDump(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__UploadMiniDump, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadMiniDump); + if (size) + *size = sizeof(_ns1__UploadMiniDump); + ((_ns1__UploadMiniDump*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__UploadMiniDump[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__UploadMiniDump); + for (int i = 0; i < n; i++) + ((_ns1__UploadMiniDump*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__UploadMiniDump*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadMiniDump(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__UploadMiniDump %p -> %p\n", q, p)); + *(_ns1__UploadMiniDump*)p = *(_ns1__UploadMiniDump*)q; +} + +void _ns1__HelloResponse::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__HelloResponse::HelloResult = NULL; + /* transient soap skipped */ +} + +void _ns1__HelloResponse::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__Response(soap, &this->_ns1__HelloResponse::HelloResult); + /* transient soap skipped */ +} + +int _ns1__HelloResponse::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__HelloResponse(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__HelloResponse(struct soap *soap, const char *tag, int id, const _ns1__HelloResponse *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__HelloResponse), type)) + return soap->error; + if (a->HelloResult) + soap_element_result(soap, "ns1:HelloResult"); + if (soap_out_PointerTons1__Response(soap, "ns1:HelloResult", -1, &(a->_ns1__HelloResponse::HelloResult), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__HelloResponse::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__HelloResponse(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__HelloResponse * SOAP_FMAC4 soap_in__ns1__HelloResponse(struct soap *soap, const char *tag, _ns1__HelloResponse *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__HelloResponse *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__HelloResponse, sizeof(_ns1__HelloResponse), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__HelloResponse) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__HelloResponse *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_HelloResult1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_HelloResult1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Response(soap, "ns1:HelloResult", &(a->_ns1__HelloResponse::HelloResult), "ns1:Response")) + { soap_flag_HelloResult1--; + continue; + } + /* transient soap skipped */ + soap_check_result(soap, "ns1:HelloResult"); + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__HelloResponse *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__HelloResponse, 0, sizeof(_ns1__HelloResponse), 0, soap_copy__ns1__HelloResponse); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +int _ns1__HelloResponse::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__HelloResponse); + if (this->soap_out(soap, tag?tag:"ns1:HelloResponse", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__HelloResponse::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__HelloResponse(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__HelloResponse * SOAP_FMAC4 soap_get__ns1__HelloResponse(struct soap *soap, _ns1__HelloResponse *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__HelloResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__HelloResponse * SOAP_FMAC2 soap_instantiate__ns1__HelloResponse(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__HelloResponse(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__HelloResponse, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__HelloResponse); + if (size) + *size = sizeof(_ns1__HelloResponse); + ((_ns1__HelloResponse*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__HelloResponse[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__HelloResponse); + for (int i = 0; i < n; i++) + ((_ns1__HelloResponse*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__HelloResponse*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__HelloResponse(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__HelloResponse %p -> %p\n", q, p)); + *(_ns1__HelloResponse*)p = *(_ns1__HelloResponse*)q; +} + +void _ns1__Hello::soap_default(struct soap *soap) +{ + this->soap = soap; + this->_ns1__Hello::client = NULL; + this->_ns1__Hello::app = NULL; + this->_ns1__Hello::mainModule = NULL; + /* transient soap skipped */ +} + +void _ns1__Hello::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTons1__ClientLib(soap, &this->_ns1__Hello::client); + soap_serialize_PointerTons1__Application(soap, &this->_ns1__Hello::app); + soap_serialize_PointerTostd__wstring(soap, &this->_ns1__Hello::mainModule); + /* transient soap skipped */ +} + +int _ns1__Hello::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out__ns1__Hello(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__Hello(struct soap *soap, const char *tag, int id, const _ns1__Hello *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__ns1__Hello), type)) + return soap->error; + if (soap_out_PointerTons1__ClientLib(soap, "ns1:client", -1, &(a->_ns1__Hello::client), "")) + return soap->error; + if (soap_out_PointerTons1__Application(soap, "ns1:app", -1, &(a->_ns1__Hello::app), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:mainModule", -1, &(a->_ns1__Hello::mainModule), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *_ns1__Hello::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in__ns1__Hello(soap, tag, this, type); +} + +SOAP_FMAC3 _ns1__Hello * SOAP_FMAC4 soap_in__ns1__Hello(struct soap *soap, const char *tag, _ns1__Hello *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (_ns1__Hello *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE__ns1__Hello, sizeof(_ns1__Hello), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE__ns1__Hello) + { soap_revert(soap); + *soap->id = '\0'; + return (_ns1__Hello *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_client1 = 1; + size_t soap_flag_app1 = 1; + size_t soap_flag_mainModule1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_client1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__ClientLib(soap, "ns1:client", &(a->_ns1__Hello::client), "ns1:ClientLib")) + { soap_flag_client1--; + continue; + } + if (soap_flag_app1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Application(soap, "ns1:app", &(a->_ns1__Hello::app), "ns1:Application")) + { soap_flag_app1--; + continue; + } + if (soap_flag_mainModule1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:mainModule", &(a->_ns1__Hello::mainModule), "xsd:string")) + { soap_flag_mainModule1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (_ns1__Hello *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__ns1__Hello, 0, sizeof(_ns1__Hello), 0, soap_copy__ns1__Hello); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +int _ns1__Hello::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE__ns1__Hello); + if (this->soap_out(soap, tag?tag:"ns1:Hello", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *_ns1__Hello::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get__ns1__Hello(soap, this, tag, type); +} + +SOAP_FMAC3 _ns1__Hello * SOAP_FMAC4 soap_get__ns1__Hello(struct soap *soap, _ns1__Hello *p, const char *tag, const char *type) +{ + if ((p = soap_in__ns1__Hello(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 _ns1__Hello * SOAP_FMAC2 soap_instantiate__ns1__Hello(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__ns1__Hello(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__ns1__Hello, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(_ns1__Hello); + if (size) + *size = sizeof(_ns1__Hello); + ((_ns1__Hello*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(_ns1__Hello[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(_ns1__Hello); + for (int i = 0; i < n; i++) + ((_ns1__Hello*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (_ns1__Hello*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__Hello(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying _ns1__Hello %p -> %p\n", q, p)); + *(_ns1__Hello*)p = *(_ns1__Hello*)q; +} + +void ns1__Solution::soap_default(struct soap *soap) +{ + this->soap = soap; + soap_default_bool(soap, &this->ns1__Solution::askConfirmation); + soap_default_ns1__SolutionType(soap, &this->ns1__Solution::type); + this->ns1__Solution::url = NULL; + this->ns1__Solution::exe = NULL; + /* transient soap skipped */ +} + +void ns1__Solution::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTostd__wstring(soap, &this->ns1__Solution::url); + soap_serialize_PointerTo_xop__Include(soap, &this->ns1__Solution::exe); + /* transient soap skipped */ +} + +int ns1__Solution::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out_ns1__Solution(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Solution(struct soap *soap, const char *tag, int id, const ns1__Solution *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__Solution), type)) + return soap->error; + if (soap_out_bool(soap, "ns1:askConfirmation", -1, &(a->ns1__Solution::askConfirmation), "")) + return soap->error; + if (soap_out_ns1__SolutionType(soap, "ns1:type", -1, &(a->ns1__Solution::type), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:url", -1, &(a->ns1__Solution::url), "")) + return soap->error; + if (soap_out_PointerTo_xop__Include(soap, "ns1:exe", -1, &(a->ns1__Solution::exe), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *ns1__Solution::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in_ns1__Solution(soap, tag, this, type); +} + +SOAP_FMAC3 ns1__Solution * SOAP_FMAC4 soap_in_ns1__Solution(struct soap *soap, const char *tag, ns1__Solution *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (ns1__Solution *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__Solution, sizeof(ns1__Solution), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE_ns1__Solution) + { soap_revert(soap); + *soap->id = '\0'; + return (ns1__Solution *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_askConfirmation1 = 1; + size_t soap_flag_type1 = 1; + size_t soap_flag_url1 = 1; + size_t soap_flag_exe1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_askConfirmation1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_bool(soap, "ns1:askConfirmation", &(a->ns1__Solution::askConfirmation), "xsd:boolean")) + { soap_flag_askConfirmation1--; + continue; + } + if (soap_flag_type1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_ns1__SolutionType(soap, "ns1:type", &(a->ns1__Solution::type), "ns1:SolutionType")) + { soap_flag_type1--; + continue; + } + if (soap_flag_url1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:url", &(a->ns1__Solution::url), "xsd:string")) + { soap_flag_url1--; + continue; + } + if (soap_flag_exe1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_xop__Include(soap, "ns1:exe", &(a->ns1__Solution::exe), "")) + { soap_flag_exe1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (ns1__Solution *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__Solution, 0, sizeof(ns1__Solution), 0, soap_copy_ns1__Solution); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_askConfirmation1 > 0 || soap_flag_type1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int ns1__Solution::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ns1__Solution); + if (this->soap_out(soap, tag?tag:"ns1:Solution", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *ns1__Solution::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get_ns1__Solution(soap, this, tag, type); +} + +SOAP_FMAC3 ns1__Solution * SOAP_FMAC4 soap_get_ns1__Solution(struct soap *soap, ns1__Solution *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__Solution(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 ns1__Solution * SOAP_FMAC2 soap_instantiate_ns1__Solution(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_ns1__Solution(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_ns1__Solution, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(ns1__Solution); + if (size) + *size = sizeof(ns1__Solution); + ((ns1__Solution*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(ns1__Solution[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(ns1__Solution); + for (int i = 0; i < n; i++) + ((ns1__Solution*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (ns1__Solution*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__Solution(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying ns1__Solution %p -> %p\n", q, p)); + *(ns1__Solution*)p = *(ns1__Solution*)q; +} + +void ns1__Response::soap_default(struct soap *soap) +{ + this->soap = soap; + soap_default_ns1__ResponseType(soap, &this->ns1__Response::type); + this->ns1__Response::error = NULL; + this->ns1__Response::solution = NULL; + this->ns1__Response::clientID = NULL; + soap_default_int(soap, &this->ns1__Response::problemID); + soap_default_int(soap, &this->ns1__Response::dumpGroupID); + soap_default_int(soap, &this->ns1__Response::dumpID); + this->ns1__Response::urlToProblem = NULL; + soap_default_ns1__AdditionalInfoType(soap, &this->ns1__Response::infoType); + this->ns1__Response::infoModule = NULL; + this->ns1__Response::infoModuleCfg = NULL; + /* transient soap skipped */ +} + +void ns1__Response::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_PointerTostd__wstring(soap, &this->ns1__Response::error); + soap_serialize_PointerTons1__Solution(soap, &this->ns1__Response::solution); + soap_serialize_PointerTostd__wstring(soap, &this->ns1__Response::clientID); + soap_serialize_PointerTostd__wstring(soap, &this->ns1__Response::urlToProblem); + soap_serialize_PointerTo_xop__Include(soap, &this->ns1__Response::infoModule); + soap_serialize_PointerTostd__wstring(soap, &this->ns1__Response::infoModuleCfg); + /* transient soap skipped */ +} + +int ns1__Response::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out_ns1__Response(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Response(struct soap *soap, const char *tag, int id, const ns1__Response *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__Response), type)) + return soap->error; + if (soap_out_ns1__ResponseType(soap, "ns1:type", -1, &(a->ns1__Response::type), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:error", -1, &(a->ns1__Response::error), "")) + return soap->error; + if (soap_out_PointerTons1__Solution(soap, "ns1:solution", -1, &(a->ns1__Response::solution), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:clientID", -1, &(a->ns1__Response::clientID), "")) + return soap->error; + if (soap_out_int(soap, "ns1:problemID", -1, &(a->ns1__Response::problemID), "")) + return soap->error; + if (soap_out_int(soap, "ns1:dumpGroupID", -1, &(a->ns1__Response::dumpGroupID), "")) + return soap->error; + if (soap_out_int(soap, "ns1:dumpID", -1, &(a->ns1__Response::dumpID), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:urlToProblem", -1, &(a->ns1__Response::urlToProblem), "")) + return soap->error; + if (soap_out_ns1__AdditionalInfoType(soap, "ns1:infoType", -1, &(a->ns1__Response::infoType), "")) + return soap->error; + if (soap_out_PointerTo_xop__Include(soap, "ns1:infoModule", -1, &(a->ns1__Response::infoModule), "")) + return soap->error; + if (soap_out_PointerTostd__wstring(soap, "ns1:infoModuleCfg", -1, &(a->ns1__Response::infoModuleCfg), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *ns1__Response::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in_ns1__Response(soap, tag, this, type); +} + +SOAP_FMAC3 ns1__Response * SOAP_FMAC4 soap_in_ns1__Response(struct soap *soap, const char *tag, ns1__Response *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (ns1__Response *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__Response, sizeof(ns1__Response), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE_ns1__Response) + { soap_revert(soap); + *soap->id = '\0'; + return (ns1__Response *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_type1 = 1; + size_t soap_flag_error1 = 1; + size_t soap_flag_solution1 = 1; + size_t soap_flag_clientID1 = 1; + size_t soap_flag_problemID1 = 1; + size_t soap_flag_dumpGroupID1 = 1; + size_t soap_flag_dumpID1 = 1; + size_t soap_flag_urlToProblem1 = 1; + size_t soap_flag_infoType1 = 1; + size_t soap_flag_infoModule1 = 1; + size_t soap_flag_infoModuleCfg1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_type1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_ns1__ResponseType(soap, "ns1:type", &(a->ns1__Response::type), "ns1:ResponseType")) + { soap_flag_type1--; + continue; + } + if (soap_flag_error1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:error", &(a->ns1__Response::error), "xsd:string")) + { soap_flag_error1--; + continue; + } + if (soap_flag_solution1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTons1__Solution(soap, "ns1:solution", &(a->ns1__Response::solution), "ns1:Solution")) + { soap_flag_solution1--; + continue; + } + if (soap_flag_clientID1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:clientID", &(a->ns1__Response::clientID), "xsd:string")) + { soap_flag_clientID1--; + continue; + } + if (soap_flag_problemID1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_int(soap, "ns1:problemID", &(a->ns1__Response::problemID), "xsd:int")) + { soap_flag_problemID1--; + continue; + } + if (soap_flag_dumpGroupID1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_int(soap, "ns1:dumpGroupID", &(a->ns1__Response::dumpGroupID), "xsd:int")) + { soap_flag_dumpGroupID1--; + continue; + } + if (soap_flag_dumpID1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_int(soap, "ns1:dumpID", &(a->ns1__Response::dumpID), "xsd:int")) + { soap_flag_dumpID1--; + continue; + } + if (soap_flag_urlToProblem1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:urlToProblem", &(a->ns1__Response::urlToProblem), "xsd:string")) + { soap_flag_urlToProblem1--; + continue; + } + if (soap_flag_infoType1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_ns1__AdditionalInfoType(soap, "ns1:infoType", &(a->ns1__Response::infoType), "ns1:AdditionalInfoType")) + { soap_flag_infoType1--; + continue; + } + if (soap_flag_infoModule1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_xop__Include(soap, "ns1:infoModule", &(a->ns1__Response::infoModule), "")) + { soap_flag_infoModule1--; + continue; + } + if (soap_flag_infoModuleCfg1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_PointerTostd__wstring(soap, "ns1:infoModuleCfg", &(a->ns1__Response::infoModuleCfg), "xsd:string")) + { soap_flag_infoModuleCfg1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (ns1__Response *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__Response, 0, sizeof(ns1__Response), 0, soap_copy_ns1__Response); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_type1 > 0 || soap_flag_problemID1 > 0 || soap_flag_dumpGroupID1 > 0 || soap_flag_dumpID1 > 0 || soap_flag_infoType1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int ns1__Response::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ns1__Response); + if (this->soap_out(soap, tag?tag:"ns1:Response", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *ns1__Response::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get_ns1__Response(soap, this, tag, type); +} + +SOAP_FMAC3 ns1__Response * SOAP_FMAC4 soap_get_ns1__Response(struct soap *soap, ns1__Response *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__Response(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 ns1__Response * SOAP_FMAC2 soap_instantiate_ns1__Response(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_ns1__Response(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_ns1__Response, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(ns1__Response); + if (size) + *size = sizeof(ns1__Response); + ((ns1__Response*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(ns1__Response[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(ns1__Response); + for (int i = 0; i < n; i++) + ((ns1__Response*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (ns1__Response*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__Response(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying ns1__Response %p -> %p\n", q, p)); + *(ns1__Response*)p = *(ns1__Response*)q; +} + +void ns1__Application::soap_default(struct soap *soap) +{ + this->soap = soap; + soap_default_ns2__guid(soap, &this->ns1__Application::applicationGUID); + soap_default_unsignedShort(soap, &this->ns1__Application::v1); + soap_default_unsignedShort(soap, &this->ns1__Application::v2); + soap_default_unsignedShort(soap, &this->ns1__Application::v3); + soap_default_unsignedShort(soap, &this->ns1__Application::v4); + soap_default_unsignedShort(soap, &this->ns1__Application::hotfix); + /* transient soap skipped */ +} + +void ns1__Application::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + soap_serialize_ns2__guid(soap, &this->ns1__Application::applicationGUID); + /* transient soap skipped */ +} + +int ns1__Application::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out_ns1__Application(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Application(struct soap *soap, const char *tag, int id, const ns1__Application *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__Application), type)) + return soap->error; + if (soap_out_ns2__guid(soap, "ns1:applicationGUID", -1, &(a->ns1__Application::applicationGUID), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v1", -1, &(a->ns1__Application::v1), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v2", -1, &(a->ns1__Application::v2), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v3", -1, &(a->ns1__Application::v3), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v4", -1, &(a->ns1__Application::v4), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:hotfix", -1, &(a->ns1__Application::hotfix), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *ns1__Application::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in_ns1__Application(soap, tag, this, type); +} + +SOAP_FMAC3 ns1__Application * SOAP_FMAC4 soap_in_ns1__Application(struct soap *soap, const char *tag, ns1__Application *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (ns1__Application *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__Application, sizeof(ns1__Application), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE_ns1__Application) + { soap_revert(soap); + *soap->id = '\0'; + return (ns1__Application *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_applicationGUID1 = 1; + size_t soap_flag_v11 = 1; + size_t soap_flag_v21 = 1; + size_t soap_flag_v31 = 1; + size_t soap_flag_v41 = 1; + size_t soap_flag_hotfix1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_applicationGUID1 && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_ns2__guid(soap, "ns1:applicationGUID", &(a->ns1__Application::applicationGUID), "ns2:guid")) + { soap_flag_applicationGUID1--; + continue; + } + if (soap_flag_v11 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v1", &(a->ns1__Application::v1), "xsd:unsignedShort")) + { soap_flag_v11--; + continue; + } + if (soap_flag_v21 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v2", &(a->ns1__Application::v2), "xsd:unsignedShort")) + { soap_flag_v21--; + continue; + } + if (soap_flag_v31 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v3", &(a->ns1__Application::v3), "xsd:unsignedShort")) + { soap_flag_v31--; + continue; + } + if (soap_flag_v41 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v4", &(a->ns1__Application::v4), "xsd:unsignedShort")) + { soap_flag_v41--; + continue; + } + if (soap_flag_hotfix1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:hotfix", &(a->ns1__Application::hotfix), "xsd:unsignedShort")) + { soap_flag_hotfix1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (ns1__Application *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__Application, 0, sizeof(ns1__Application), 0, soap_copy_ns1__Application); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_applicationGUID1 > 0 || soap_flag_v11 > 0 || soap_flag_v21 > 0 || soap_flag_v31 > 0 || soap_flag_v41 > 0 || soap_flag_hotfix1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int ns1__Application::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ns1__Application); + if (this->soap_out(soap, tag?tag:"ns1:Application", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *ns1__Application::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get_ns1__Application(soap, this, tag, type); +} + +SOAP_FMAC3 ns1__Application * SOAP_FMAC4 soap_get_ns1__Application(struct soap *soap, ns1__Application *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__Application(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 ns1__Application * SOAP_FMAC2 soap_instantiate_ns1__Application(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_ns1__Application(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_ns1__Application, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(ns1__Application); + if (size) + *size = sizeof(ns1__Application); + ((ns1__Application*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(ns1__Application[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(ns1__Application); + for (int i = 0; i < n; i++) + ((ns1__Application*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (ns1__Application*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__Application(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying ns1__Application %p -> %p\n", q, p)); + *(ns1__Application*)p = *(ns1__Application*)q; +} + +void ns1__ClientLib::soap_default(struct soap *soap) +{ + this->soap = soap; + soap_default_unsignedShort(soap, &this->ns1__ClientLib::v1); + soap_default_unsignedShort(soap, &this->ns1__ClientLib::v2); + soap_default_unsignedShort(soap, &this->ns1__ClientLib::v3); + soap_default_unsignedShort(soap, &this->ns1__ClientLib::v4); + soap_default_ns1__Architecture(soap, &this->ns1__ClientLib::arch); + /* transient soap skipped */ +} + +void ns1__ClientLib::soap_serialize(struct soap *soap) const +{ + (void)soap; /* appease -Wall -Werror */ + /* transient soap skipped */ +} + +int ns1__ClientLib::soap_out(struct soap *soap, const char *tag, int id, const char *type) const +{ + return soap_out_ns1__ClientLib(soap, tag, id, this, type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__ClientLib(struct soap *soap, const char *tag, int id, const ns1__ClientLib *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__ClientLib), type)) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v1", -1, &(a->ns1__ClientLib::v1), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v2", -1, &(a->ns1__ClientLib::v2), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v3", -1, &(a->ns1__ClientLib::v3), "")) + return soap->error; + if (soap_out_unsignedShort(soap, "ns1:v4", -1, &(a->ns1__ClientLib::v4), "")) + return soap->error; + if (soap_out_ns1__Architecture(soap, "ns1:arch", -1, &(a->ns1__ClientLib::arch), "")) + return soap->error; + /* transient soap skipped */ + return soap_element_end_out(soap, tag); +} + +void *ns1__ClientLib::soap_in(struct soap *soap, const char *tag, const char *type) +{ return soap_in_ns1__ClientLib(soap, tag, this, type); +} + +SOAP_FMAC3 ns1__ClientLib * SOAP_FMAC4 soap_in_ns1__ClientLib(struct soap *soap, const char *tag, ns1__ClientLib *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + a = (ns1__ClientLib *)soap_class_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__ClientLib, sizeof(ns1__ClientLib), soap->type, soap->arrayType); + if (!a) + return NULL; + if (soap->alloced) + { a->soap_default(soap); + if (soap->clist->type != SOAP_TYPE_ns1__ClientLib) + { soap_revert(soap); + *soap->id = '\0'; + return (ns1__ClientLib *)a->soap_in(soap, tag, type); + } + } + size_t soap_flag_v11 = 1; + size_t soap_flag_v21 = 1; + size_t soap_flag_v31 = 1; + size_t soap_flag_v41 = 1; + size_t soap_flag_arch1 = 1; + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_v11 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v1", &(a->ns1__ClientLib::v1), "xsd:unsignedShort")) + { soap_flag_v11--; + continue; + } + if (soap_flag_v21 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v2", &(a->ns1__ClientLib::v2), "xsd:unsignedShort")) + { soap_flag_v21--; + continue; + } + if (soap_flag_v31 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v3", &(a->ns1__ClientLib::v3), "xsd:unsignedShort")) + { soap_flag_v31--; + continue; + } + if (soap_flag_v41 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_unsignedShort(soap, "ns1:v4", &(a->ns1__ClientLib::v4), "xsd:unsignedShort")) + { soap_flag_v41--; + continue; + } + if (soap_flag_arch1 && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_ns1__Architecture(soap, "ns1:arch", &(a->ns1__ClientLib::arch), "ns1:Architecture")) + { soap_flag_arch1--; + continue; + } + /* transient soap skipped */ + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (ns1__ClientLib *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__ClientLib, 0, sizeof(ns1__ClientLib), 0, soap_copy_ns1__ClientLib); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_v11 > 0 || soap_flag_v21 > 0 || soap_flag_v31 > 0 || soap_flag_v41 > 0 || soap_flag_arch1 > 0)) + { soap->error = SOAP_OCCURS; + return NULL; + } + return a; +} + +int ns1__ClientLib::soap_put(struct soap *soap, const char *tag, const char *type) const +{ + register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ns1__ClientLib); + if (this->soap_out(soap, tag?tag:"ns1:ClientLib", id, type)) + return soap->error; + return soap_putindependent(soap); +} + +void *ns1__ClientLib::soap_get(struct soap *soap, const char *tag, const char *type) +{ + return soap_get_ns1__ClientLib(soap, this, tag, type); +} + +SOAP_FMAC3 ns1__ClientLib * SOAP_FMAC4 soap_get_ns1__ClientLib(struct soap *soap, ns1__ClientLib *p, const char *tag, const char *type) +{ + if ((p = soap_in_ns1__ClientLib(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 ns1__ClientLib * SOAP_FMAC2 soap_instantiate_ns1__ClientLib(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_ns1__ClientLib(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_ns1__ClientLib, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(ns1__ClientLib); + if (size) + *size = sizeof(ns1__ClientLib); + ((ns1__ClientLib*)cp->ptr)->soap = soap; + } + else + { cp->ptr = (void*)SOAP_NEW(ns1__ClientLib[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(ns1__ClientLib); + for (int i = 0; i < n; i++) + ((ns1__ClientLib*)cp->ptr)[i].soap = soap; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (ns1__ClientLib*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__ClientLib(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying ns1__ClientLib %p -> %p\n", q, p)); + *(ns1__ClientLib*)p = *(ns1__ClientLib*)q; +} + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Fault(struct soap *soap, struct SOAP_ENV__Fault *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_default__QName(soap, &a->faultcode); + soap_default_string(soap, &a->faultstring); + soap_default_string(soap, &a->faultactor); + a->detail = NULL; + a->SOAP_ENV__Code = NULL; + a->SOAP_ENV__Reason = NULL; + soap_default_string(soap, &a->SOAP_ENV__Node); + soap_default_string(soap, &a->SOAP_ENV__Role); + a->SOAP_ENV__Detail = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Fault(struct soap *soap, const struct SOAP_ENV__Fault *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize__QName(soap, &a->faultcode); + soap_serialize_string(soap, &a->faultstring); + soap_serialize_string(soap, &a->faultactor); + soap_serialize_PointerToSOAP_ENV__Detail(soap, &a->detail); + soap_serialize_PointerToSOAP_ENV__Code(soap, &a->SOAP_ENV__Code); + soap_serialize_PointerToSOAP_ENV__Reason(soap, &a->SOAP_ENV__Reason); + soap_serialize_string(soap, &a->SOAP_ENV__Node); + soap_serialize_string(soap, &a->SOAP_ENV__Role); + soap_serialize_PointerToSOAP_ENV__Detail(soap, &a->SOAP_ENV__Detail); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Fault(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Fault *a, const char *type) +{ + const char *soap_tmp_faultcode = soap_QName2s(soap, a->faultcode); + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Fault), type)) + return soap->error; + if (soap_out__QName(soap, "faultcode", -1, (char*const*)&soap_tmp_faultcode, "")) + return soap->error; + if (soap_out_string(soap, "faultstring", -1, &a->faultstring, "")) + return soap->error; + if (soap_out_string(soap, "faultactor", -1, &a->faultactor, "")) + return soap->error; + if (soap_out_PointerToSOAP_ENV__Detail(soap, "detail", -1, &a->detail, "")) + return soap->error; + if (soap_out_PointerToSOAP_ENV__Code(soap, "SOAP-ENV:Code", -1, &a->SOAP_ENV__Code, "")) + return soap->error; + if (soap_out_PointerToSOAP_ENV__Reason(soap, "SOAP-ENV:Reason", -1, &a->SOAP_ENV__Reason, "")) + return soap->error; + if (soap_out_string(soap, "SOAP-ENV:Node", -1, &a->SOAP_ENV__Node, "")) + return soap->error; + if (soap_out_string(soap, "SOAP-ENV:Role", -1, &a->SOAP_ENV__Role, "")) + return soap->error; + if (soap_out_PointerToSOAP_ENV__Detail(soap, "SOAP-ENV:Detail", -1, &a->SOAP_ENV__Detail, "")) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_in_SOAP_ENV__Fault(struct soap *soap, const char *tag, struct SOAP_ENV__Fault *a, const char *type) +{ + size_t soap_flag_faultcode = 1; + size_t soap_flag_faultstring = 1; + size_t soap_flag_faultactor = 1; + size_t soap_flag_detail = 1; + size_t soap_flag_SOAP_ENV__Code = 1; + size_t soap_flag_SOAP_ENV__Reason = 1; + size_t soap_flag_SOAP_ENV__Node = 1; + size_t soap_flag_SOAP_ENV__Role = 1; + size_t soap_flag_SOAP_ENV__Detail = 1; + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (struct SOAP_ENV__Fault *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Fault, sizeof(struct SOAP_ENV__Fault), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default_SOAP_ENV__Fault(soap, a); + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_faultcode && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in__QName(soap, "faultcode", &a->faultcode, "")) + { soap_flag_faultcode--; + continue; + } + if (soap_flag_faultstring && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_string(soap, "faultstring", &a->faultstring, "xsd:string")) + { soap_flag_faultstring--; + continue; + } + if (soap_flag_faultactor && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_string(soap, "faultactor", &a->faultactor, "xsd:string")) + { soap_flag_faultactor--; + continue; + } + if (soap_flag_detail && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerToSOAP_ENV__Detail(soap, "detail", &a->detail, "")) + { soap_flag_detail--; + continue; + } + if (soap_flag_SOAP_ENV__Code && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerToSOAP_ENV__Code(soap, "SOAP-ENV:Code", &a->SOAP_ENV__Code, "")) + { soap_flag_SOAP_ENV__Code--; + continue; + } + if (soap_flag_SOAP_ENV__Reason && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerToSOAP_ENV__Reason(soap, "SOAP-ENV:Reason", &a->SOAP_ENV__Reason, "")) + { soap_flag_SOAP_ENV__Reason--; + continue; + } + if (soap_flag_SOAP_ENV__Node && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_string(soap, "SOAP-ENV:Node", &a->SOAP_ENV__Node, "xsd:string")) + { soap_flag_SOAP_ENV__Node--; + continue; + } + if (soap_flag_SOAP_ENV__Role && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_string(soap, "SOAP-ENV:Role", &a->SOAP_ENV__Role, "xsd:string")) + { soap_flag_SOAP_ENV__Role--; + continue; + } + if (soap_flag_SOAP_ENV__Detail && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerToSOAP_ENV__Detail(soap, "SOAP-ENV:Detail", &a->SOAP_ENV__Detail, "")) + { soap_flag_SOAP_ENV__Detail--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (struct SOAP_ENV__Fault *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Fault, 0, sizeof(struct SOAP_ENV__Fault), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Fault(struct soap *soap, const struct SOAP_ENV__Fault *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Fault); + if (soap_out_SOAP_ENV__Fault(soap, tag?tag:"SOAP-ENV:Fault", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_get_SOAP_ENV__Fault(struct soap *soap, struct SOAP_ENV__Fault *p, const char *tag, const char *type) +{ + if ((p = soap_in_SOAP_ENV__Fault(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct SOAP_ENV__Fault * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Fault(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_SOAP_ENV__Fault(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_SOAP_ENV__Fault, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Fault); + if (size) + *size = sizeof(struct SOAP_ENV__Fault); + } + else + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Fault[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct SOAP_ENV__Fault); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct SOAP_ENV__Fault*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Fault(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct SOAP_ENV__Fault %p -> %p\n", q, p)); + *(struct SOAP_ENV__Fault*)p = *(struct SOAP_ENV__Fault*)q; +} + +#endif + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_default_string(soap, &a->SOAP_ENV__Text); +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Reason(struct soap *soap, const struct SOAP_ENV__Reason *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_string(soap, &a->SOAP_ENV__Text); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Reason(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Reason *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Reason), type)) + return soap->error; + if (soap->lang) + soap_set_attr(soap, "xml:lang", soap->lang, 1); + if (soap_out_string(soap, "SOAP-ENV:Text", -1, &a->SOAP_ENV__Text, "")) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_in_SOAP_ENV__Reason(struct soap *soap, const char *tag, struct SOAP_ENV__Reason *a, const char *type) +{ + size_t soap_flag_SOAP_ENV__Text = 1; + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (struct SOAP_ENV__Reason *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Reason, sizeof(struct SOAP_ENV__Reason), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default_SOAP_ENV__Reason(soap, a); + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_SOAP_ENV__Text && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in_string(soap, "SOAP-ENV:Text", &a->SOAP_ENV__Text, "xsd:string")) + { soap_flag_SOAP_ENV__Text--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (struct SOAP_ENV__Reason *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Reason, 0, sizeof(struct SOAP_ENV__Reason), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Reason(struct soap *soap, const struct SOAP_ENV__Reason *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Reason); + if (soap_out_SOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_get_SOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *p, const char *tag, const char *type) +{ + if ((p = soap_in_SOAP_ENV__Reason(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct SOAP_ENV__Reason * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Reason(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_SOAP_ENV__Reason(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_SOAP_ENV__Reason, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Reason); + if (size) + *size = sizeof(struct SOAP_ENV__Reason); + } + else + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Reason[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct SOAP_ENV__Reason); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct SOAP_ENV__Reason*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Reason(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct SOAP_ENV__Reason %p -> %p\n", q, p)); + *(struct SOAP_ENV__Reason*)p = *(struct SOAP_ENV__Reason*)q; +} + +#endif + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->__type = 0; + a->fault = NULL; + a->__any = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Detail(struct soap *soap, const struct SOAP_ENV__Detail *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_markelement(soap, a->fault, a->__type); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Detail(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Detail *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Detail), type)) + return soap->error; + if (soap_putelement(soap, a->fault, "fault", -1, a->__type)) + return soap->error; + soap_outliteral(soap, "-any", &a->__any, NULL); + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_in_SOAP_ENV__Detail(struct soap *soap, const char *tag, struct SOAP_ENV__Detail *a, const char *type) +{ + size_t soap_flag_fault = 1; + size_t soap_flag___any = 1; + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (struct SOAP_ENV__Detail *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Detail, sizeof(struct SOAP_ENV__Detail), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default_SOAP_ENV__Detail(soap, a); + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_fault && soap->error == SOAP_TAG_MISMATCH) + if ((a->fault = soap_getelement(soap, &a->__type))) + { soap_flag_fault = 0; + continue; + } + if (soap_flag___any && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_inliteral(soap, "-any", &a->__any)) + { soap_flag___any--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (struct SOAP_ENV__Detail *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Detail, 0, sizeof(struct SOAP_ENV__Detail), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Detail(struct soap *soap, const struct SOAP_ENV__Detail *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Detail); + if (soap_out_SOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_get_SOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *p, const char *tag, const char *type) +{ + if ((p = soap_in_SOAP_ENV__Detail(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct SOAP_ENV__Detail * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Detail(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_SOAP_ENV__Detail(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_SOAP_ENV__Detail, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Detail); + if (size) + *size = sizeof(struct SOAP_ENV__Detail); + } + else + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Detail[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct SOAP_ENV__Detail); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct SOAP_ENV__Detail*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Detail(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct SOAP_ENV__Detail %p -> %p\n", q, p)); + *(struct SOAP_ENV__Detail*)p = *(struct SOAP_ENV__Detail*)q; +} + +#endif + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_default__QName(soap, &a->SOAP_ENV__Value); + a->SOAP_ENV__Subcode = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Code(struct soap *soap, const struct SOAP_ENV__Code *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize__QName(soap, &a->SOAP_ENV__Value); + soap_serialize_PointerToSOAP_ENV__Code(soap, &a->SOAP_ENV__Subcode); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Code(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Code *a, const char *type) +{ + const char *soap_tmp_SOAP_ENV__Value = soap_QName2s(soap, a->SOAP_ENV__Value); + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Code), type)) + return soap->error; + if (soap_out__QName(soap, "SOAP-ENV:Value", -1, (char*const*)&soap_tmp_SOAP_ENV__Value, "")) + return soap->error; + if (soap_out_PointerToSOAP_ENV__Code(soap, "SOAP-ENV:Subcode", -1, &a->SOAP_ENV__Subcode, "")) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_in_SOAP_ENV__Code(struct soap *soap, const char *tag, struct SOAP_ENV__Code *a, const char *type) +{ + size_t soap_flag_SOAP_ENV__Value = 1; + size_t soap_flag_SOAP_ENV__Subcode = 1; + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (struct SOAP_ENV__Code *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Code, sizeof(struct SOAP_ENV__Code), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default_SOAP_ENV__Code(soap, a); + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_SOAP_ENV__Value && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG)) + if (soap_in__QName(soap, "SOAP-ENV:Value", &a->SOAP_ENV__Value, "")) + { soap_flag_SOAP_ENV__Value--; + continue; + } + if (soap_flag_SOAP_ENV__Subcode && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerToSOAP_ENV__Code(soap, "SOAP-ENV:Subcode", &a->SOAP_ENV__Subcode, "")) + { soap_flag_SOAP_ENV__Subcode--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (struct SOAP_ENV__Code *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Code, 0, sizeof(struct SOAP_ENV__Code), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Code(struct soap *soap, const struct SOAP_ENV__Code *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Code); + if (soap_out_SOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_get_SOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *p, const char *tag, const char *type) +{ + if ((p = soap_in_SOAP_ENV__Code(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct SOAP_ENV__Code * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Code(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_SOAP_ENV__Code(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_SOAP_ENV__Code, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Code); + if (size) + *size = sizeof(struct SOAP_ENV__Code); + } + else + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Code[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct SOAP_ENV__Code); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct SOAP_ENV__Code*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Code(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct SOAP_ENV__Code %p -> %p\n", q, p)); + *(struct SOAP_ENV__Code*)p = *(struct SOAP_ENV__Code*)q; +} + +#endif + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Header(struct soap *soap, struct SOAP_ENV__Header *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Header(struct soap *soap, const struct SOAP_ENV__Header *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Header(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Header *a, const char *type) +{ + if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Header), type)) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_in_SOAP_ENV__Header(struct soap *soap, const char *tag, struct SOAP_ENV__Header *a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 0, type)) + return NULL; + a = (struct SOAP_ENV__Header *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_SOAP_ENV__Header, sizeof(struct SOAP_ENV__Header), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default_SOAP_ENV__Header(soap, a); + if (soap->body && !*soap->href) + { + for (;;) + { soap->error = SOAP_TAG_MISMATCH; + if (soap->error == SOAP_TAG_MISMATCH) + soap->error = soap_ignore_element(soap); + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + if (soap_element_end_in(soap, tag)) + return NULL; + } + else + { a = (struct SOAP_ENV__Header *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_SOAP_ENV__Header, 0, sizeof(struct SOAP_ENV__Header), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Header(struct soap *soap, const struct SOAP_ENV__Header *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Header); + if (soap_out_SOAP_ENV__Header(soap, tag?tag:"SOAP-ENV:Header", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_get_SOAP_ENV__Header(struct soap *soap, struct SOAP_ENV__Header *p, const char *tag, const char *type) +{ + if ((p = soap_in_SOAP_ENV__Header(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct SOAP_ENV__Header * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Header(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate_SOAP_ENV__Header(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE_SOAP_ENV__Header, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Header); + if (size) + *size = sizeof(struct SOAP_ENV__Header); + } + else + { cp->ptr = (void*)SOAP_NEW(struct SOAP_ENV__Header[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct SOAP_ENV__Header); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct SOAP_ENV__Header*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Header(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct SOAP_ENV__Header %p -> %p\n", q, p)); + *(struct SOAP_ENV__Header*)p = *(struct SOAP_ENV__Header*)q; +} + +#endif + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__UploadSymbol(struct soap *soap, struct __ns4__UploadSymbol *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__UploadSymbol = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__UploadSymbol(struct soap *soap, const struct __ns4__UploadSymbol *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__UploadSymbol(soap, &a->ns1__UploadSymbol); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__UploadSymbol(struct soap *soap, const char *tag, int id, const struct __ns4__UploadSymbol *a, const char *type) +{ + if (soap_out_PointerTo_ns1__UploadSymbol(soap, "ns1:UploadSymbol", -1, &a->ns1__UploadSymbol, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__UploadSymbol * SOAP_FMAC4 soap_in___ns4__UploadSymbol(struct soap *soap, const char *tag, struct __ns4__UploadSymbol *a, const char *type) +{ + size_t soap_flag_ns1__UploadSymbol = 1; + short soap_flag; + a = (struct __ns4__UploadSymbol *)soap_id_enter(soap, "", a, SOAP_TYPE___ns4__UploadSymbol, sizeof(struct __ns4__UploadSymbol), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns4__UploadSymbol(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__UploadSymbol && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__UploadSymbol(soap, "ns1:UploadSymbol", &a->ns1__UploadSymbol, "")) + { soap_flag_ns1__UploadSymbol--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__UploadSymbol(struct soap *soap, const struct __ns4__UploadSymbol *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns4__UploadSymbol(soap, tag?tag:"-ns4:UploadSymbol", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__UploadSymbol * SOAP_FMAC4 soap_get___ns4__UploadSymbol(struct soap *soap, struct __ns4__UploadSymbol *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns4__UploadSymbol(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns4__UploadSymbol * SOAP_FMAC2 soap_instantiate___ns4__UploadSymbol(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns4__UploadSymbol(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns4__UploadSymbol, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns4__UploadSymbol); + if (size) + *size = sizeof(struct __ns4__UploadSymbol); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns4__UploadSymbol[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns4__UploadSymbol); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns4__UploadSymbol*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__UploadSymbol(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns4__UploadSymbol %p -> %p\n", q, p)); + *(struct __ns4__UploadSymbol*)p = *(struct __ns4__UploadSymbol*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__UploadAdditionalInfo(struct soap *soap, struct __ns4__UploadAdditionalInfo *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__UploadAdditionalInfo = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__UploadAdditionalInfo(struct soap *soap, const struct __ns4__UploadAdditionalInfo *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__UploadAdditionalInfo(soap, &a->ns1__UploadAdditionalInfo); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__UploadAdditionalInfo(struct soap *soap, const char *tag, int id, const struct __ns4__UploadAdditionalInfo *a, const char *type) +{ + if (soap_out_PointerTo_ns1__UploadAdditionalInfo(soap, "ns1:UploadAdditionalInfo", -1, &a->ns1__UploadAdditionalInfo, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__UploadAdditionalInfo * SOAP_FMAC4 soap_in___ns4__UploadAdditionalInfo(struct soap *soap, const char *tag, struct __ns4__UploadAdditionalInfo *a, const char *type) +{ + size_t soap_flag_ns1__UploadAdditionalInfo = 1; + short soap_flag; + a = (struct __ns4__UploadAdditionalInfo *)soap_id_enter(soap, "", a, SOAP_TYPE___ns4__UploadAdditionalInfo, sizeof(struct __ns4__UploadAdditionalInfo), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns4__UploadAdditionalInfo(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__UploadAdditionalInfo && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__UploadAdditionalInfo(soap, "ns1:UploadAdditionalInfo", &a->ns1__UploadAdditionalInfo, "")) + { soap_flag_ns1__UploadAdditionalInfo--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__UploadAdditionalInfo(struct soap *soap, const struct __ns4__UploadAdditionalInfo *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns4__UploadAdditionalInfo(soap, tag?tag:"-ns4:UploadAdditionalInfo", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__UploadAdditionalInfo * SOAP_FMAC4 soap_get___ns4__UploadAdditionalInfo(struct soap *soap, struct __ns4__UploadAdditionalInfo *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns4__UploadAdditionalInfo(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns4__UploadAdditionalInfo * SOAP_FMAC2 soap_instantiate___ns4__UploadAdditionalInfo(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns4__UploadAdditionalInfo(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns4__UploadAdditionalInfo, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns4__UploadAdditionalInfo); + if (size) + *size = sizeof(struct __ns4__UploadAdditionalInfo); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns4__UploadAdditionalInfo[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns4__UploadAdditionalInfo); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns4__UploadAdditionalInfo*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__UploadAdditionalInfo(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns4__UploadAdditionalInfo %p -> %p\n", q, p)); + *(struct __ns4__UploadAdditionalInfo*)p = *(struct __ns4__UploadAdditionalInfo*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__UploadMiniDump(struct soap *soap, struct __ns4__UploadMiniDump *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__UploadMiniDump = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__UploadMiniDump(struct soap *soap, const struct __ns4__UploadMiniDump *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__UploadMiniDump(soap, &a->ns1__UploadMiniDump); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__UploadMiniDump(struct soap *soap, const char *tag, int id, const struct __ns4__UploadMiniDump *a, const char *type) +{ + if (soap_out_PointerTo_ns1__UploadMiniDump(soap, "ns1:UploadMiniDump", -1, &a->ns1__UploadMiniDump, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__UploadMiniDump * SOAP_FMAC4 soap_in___ns4__UploadMiniDump(struct soap *soap, const char *tag, struct __ns4__UploadMiniDump *a, const char *type) +{ + size_t soap_flag_ns1__UploadMiniDump = 1; + short soap_flag; + a = (struct __ns4__UploadMiniDump *)soap_id_enter(soap, "", a, SOAP_TYPE___ns4__UploadMiniDump, sizeof(struct __ns4__UploadMiniDump), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns4__UploadMiniDump(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__UploadMiniDump && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__UploadMiniDump(soap, "ns1:UploadMiniDump", &a->ns1__UploadMiniDump, "")) + { soap_flag_ns1__UploadMiniDump--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__UploadMiniDump(struct soap *soap, const struct __ns4__UploadMiniDump *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns4__UploadMiniDump(soap, tag?tag:"-ns4:UploadMiniDump", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__UploadMiniDump * SOAP_FMAC4 soap_get___ns4__UploadMiniDump(struct soap *soap, struct __ns4__UploadMiniDump *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns4__UploadMiniDump(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns4__UploadMiniDump * SOAP_FMAC2 soap_instantiate___ns4__UploadMiniDump(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns4__UploadMiniDump(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns4__UploadMiniDump, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns4__UploadMiniDump); + if (size) + *size = sizeof(struct __ns4__UploadMiniDump); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns4__UploadMiniDump[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns4__UploadMiniDump); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns4__UploadMiniDump*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__UploadMiniDump(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns4__UploadMiniDump %p -> %p\n", q, p)); + *(struct __ns4__UploadMiniDump*)p = *(struct __ns4__UploadMiniDump*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__Hello(struct soap *soap, struct __ns4__Hello *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__Hello = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__Hello(struct soap *soap, const struct __ns4__Hello *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__Hello(soap, &a->ns1__Hello); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__Hello(struct soap *soap, const char *tag, int id, const struct __ns4__Hello *a, const char *type) +{ + if (soap_out_PointerTo_ns1__Hello(soap, "ns1:Hello", -1, &a->ns1__Hello, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__Hello * SOAP_FMAC4 soap_in___ns4__Hello(struct soap *soap, const char *tag, struct __ns4__Hello *a, const char *type) +{ + size_t soap_flag_ns1__Hello = 1; + short soap_flag; + a = (struct __ns4__Hello *)soap_id_enter(soap, "", a, SOAP_TYPE___ns4__Hello, sizeof(struct __ns4__Hello), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns4__Hello(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__Hello && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__Hello(soap, "ns1:Hello", &a->ns1__Hello, "")) + { soap_flag_ns1__Hello--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__Hello(struct soap *soap, const struct __ns4__Hello *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns4__Hello(soap, tag?tag:"-ns4:Hello", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns4__Hello * SOAP_FMAC4 soap_get___ns4__Hello(struct soap *soap, struct __ns4__Hello *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns4__Hello(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns4__Hello * SOAP_FMAC2 soap_instantiate___ns4__Hello(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns4__Hello(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns4__Hello, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns4__Hello); + if (size) + *size = sizeof(struct __ns4__Hello); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns4__Hello[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns4__Hello); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns4__Hello*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__Hello(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns4__Hello %p -> %p\n", q, p)); + *(struct __ns4__Hello*)p = *(struct __ns4__Hello*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__UploadSymbol(struct soap *soap, struct __ns3__UploadSymbol *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__UploadSymbol = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__UploadSymbol(struct soap *soap, const struct __ns3__UploadSymbol *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__UploadSymbol(soap, &a->ns1__UploadSymbol); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__UploadSymbol(struct soap *soap, const char *tag, int id, const struct __ns3__UploadSymbol *a, const char *type) +{ + if (soap_out_PointerTo_ns1__UploadSymbol(soap, "ns1:UploadSymbol", -1, &a->ns1__UploadSymbol, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__UploadSymbol * SOAP_FMAC4 soap_in___ns3__UploadSymbol(struct soap *soap, const char *tag, struct __ns3__UploadSymbol *a, const char *type) +{ + size_t soap_flag_ns1__UploadSymbol = 1; + short soap_flag; + a = (struct __ns3__UploadSymbol *)soap_id_enter(soap, "", a, SOAP_TYPE___ns3__UploadSymbol, sizeof(struct __ns3__UploadSymbol), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns3__UploadSymbol(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__UploadSymbol && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__UploadSymbol(soap, "ns1:UploadSymbol", &a->ns1__UploadSymbol, "")) + { soap_flag_ns1__UploadSymbol--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__UploadSymbol(struct soap *soap, const struct __ns3__UploadSymbol *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns3__UploadSymbol(soap, tag?tag:"-ns3:UploadSymbol", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__UploadSymbol * SOAP_FMAC4 soap_get___ns3__UploadSymbol(struct soap *soap, struct __ns3__UploadSymbol *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns3__UploadSymbol(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns3__UploadSymbol * SOAP_FMAC2 soap_instantiate___ns3__UploadSymbol(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns3__UploadSymbol(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns3__UploadSymbol, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns3__UploadSymbol); + if (size) + *size = sizeof(struct __ns3__UploadSymbol); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns3__UploadSymbol[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns3__UploadSymbol); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns3__UploadSymbol*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__UploadSymbol(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns3__UploadSymbol %p -> %p\n", q, p)); + *(struct __ns3__UploadSymbol*)p = *(struct __ns3__UploadSymbol*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__UploadAdditionalInfo(struct soap *soap, struct __ns3__UploadAdditionalInfo *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__UploadAdditionalInfo = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__UploadAdditionalInfo(struct soap *soap, const struct __ns3__UploadAdditionalInfo *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__UploadAdditionalInfo(soap, &a->ns1__UploadAdditionalInfo); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__UploadAdditionalInfo(struct soap *soap, const char *tag, int id, const struct __ns3__UploadAdditionalInfo *a, const char *type) +{ + if (soap_out_PointerTo_ns1__UploadAdditionalInfo(soap, "ns1:UploadAdditionalInfo", -1, &a->ns1__UploadAdditionalInfo, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__UploadAdditionalInfo * SOAP_FMAC4 soap_in___ns3__UploadAdditionalInfo(struct soap *soap, const char *tag, struct __ns3__UploadAdditionalInfo *a, const char *type) +{ + size_t soap_flag_ns1__UploadAdditionalInfo = 1; + short soap_flag; + a = (struct __ns3__UploadAdditionalInfo *)soap_id_enter(soap, "", a, SOAP_TYPE___ns3__UploadAdditionalInfo, sizeof(struct __ns3__UploadAdditionalInfo), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns3__UploadAdditionalInfo(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__UploadAdditionalInfo && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__UploadAdditionalInfo(soap, "ns1:UploadAdditionalInfo", &a->ns1__UploadAdditionalInfo, "")) + { soap_flag_ns1__UploadAdditionalInfo--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__UploadAdditionalInfo(struct soap *soap, const struct __ns3__UploadAdditionalInfo *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns3__UploadAdditionalInfo(soap, tag?tag:"-ns3:UploadAdditionalInfo", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__UploadAdditionalInfo * SOAP_FMAC4 soap_get___ns3__UploadAdditionalInfo(struct soap *soap, struct __ns3__UploadAdditionalInfo *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns3__UploadAdditionalInfo(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns3__UploadAdditionalInfo * SOAP_FMAC2 soap_instantiate___ns3__UploadAdditionalInfo(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns3__UploadAdditionalInfo(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns3__UploadAdditionalInfo, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns3__UploadAdditionalInfo); + if (size) + *size = sizeof(struct __ns3__UploadAdditionalInfo); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns3__UploadAdditionalInfo[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns3__UploadAdditionalInfo); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns3__UploadAdditionalInfo*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__UploadAdditionalInfo(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns3__UploadAdditionalInfo %p -> %p\n", q, p)); + *(struct __ns3__UploadAdditionalInfo*)p = *(struct __ns3__UploadAdditionalInfo*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__UploadMiniDump(struct soap *soap, struct __ns3__UploadMiniDump *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__UploadMiniDump = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__UploadMiniDump(struct soap *soap, const struct __ns3__UploadMiniDump *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__UploadMiniDump(soap, &a->ns1__UploadMiniDump); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__UploadMiniDump(struct soap *soap, const char *tag, int id, const struct __ns3__UploadMiniDump *a, const char *type) +{ + if (soap_out_PointerTo_ns1__UploadMiniDump(soap, "ns1:UploadMiniDump", -1, &a->ns1__UploadMiniDump, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__UploadMiniDump * SOAP_FMAC4 soap_in___ns3__UploadMiniDump(struct soap *soap, const char *tag, struct __ns3__UploadMiniDump *a, const char *type) +{ + size_t soap_flag_ns1__UploadMiniDump = 1; + short soap_flag; + a = (struct __ns3__UploadMiniDump *)soap_id_enter(soap, "", a, SOAP_TYPE___ns3__UploadMiniDump, sizeof(struct __ns3__UploadMiniDump), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns3__UploadMiniDump(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__UploadMiniDump && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__UploadMiniDump(soap, "ns1:UploadMiniDump", &a->ns1__UploadMiniDump, "")) + { soap_flag_ns1__UploadMiniDump--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__UploadMiniDump(struct soap *soap, const struct __ns3__UploadMiniDump *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns3__UploadMiniDump(soap, tag?tag:"-ns3:UploadMiniDump", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__UploadMiniDump * SOAP_FMAC4 soap_get___ns3__UploadMiniDump(struct soap *soap, struct __ns3__UploadMiniDump *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns3__UploadMiniDump(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns3__UploadMiniDump * SOAP_FMAC2 soap_instantiate___ns3__UploadMiniDump(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns3__UploadMiniDump(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns3__UploadMiniDump, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns3__UploadMiniDump); + if (size) + *size = sizeof(struct __ns3__UploadMiniDump); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns3__UploadMiniDump[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns3__UploadMiniDump); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns3__UploadMiniDump*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__UploadMiniDump(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns3__UploadMiniDump %p -> %p\n", q, p)); + *(struct __ns3__UploadMiniDump*)p = *(struct __ns3__UploadMiniDump*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__Hello(struct soap *soap, struct __ns3__Hello *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + a->ns1__Hello = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__Hello(struct soap *soap, const struct __ns3__Hello *a) +{ + (void)soap; (void)a; /* appease -Wall -Werror */ + soap_serialize_PointerTo_ns1__Hello(soap, &a->ns1__Hello); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__Hello(struct soap *soap, const char *tag, int id, const struct __ns3__Hello *a, const char *type) +{ + if (soap_out_PointerTo_ns1__Hello(soap, "ns1:Hello", -1, &a->ns1__Hello, "")) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__Hello * SOAP_FMAC4 soap_in___ns3__Hello(struct soap *soap, const char *tag, struct __ns3__Hello *a, const char *type) +{ + size_t soap_flag_ns1__Hello = 1; + short soap_flag; + a = (struct __ns3__Hello *)soap_id_enter(soap, "", a, SOAP_TYPE___ns3__Hello, sizeof(struct __ns3__Hello), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default___ns3__Hello(soap, a); + for (soap_flag = 0;; soap_flag = 1) + { soap->error = SOAP_TAG_MISMATCH; + if (soap_flag_ns1__Hello && soap->error == SOAP_TAG_MISMATCH) + if (soap_in_PointerTo_ns1__Hello(soap, "ns1:Hello", &a->ns1__Hello, "")) + { soap_flag_ns1__Hello--; + continue; + } + if (soap->error == SOAP_TAG_MISMATCH) + if (soap_flag) + { soap->error = SOAP_OK; + break; + } + if (soap->error == SOAP_NO_TAG) + break; + if (soap->error) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__Hello(struct soap *soap, const struct __ns3__Hello *a, const char *tag, const char *type) +{ + register int id = 0; + if (soap_out___ns3__Hello(soap, tag?tag:"-ns3:Hello", id, a, type)) + return soap->error; + return SOAP_OK; +} + +SOAP_FMAC3 struct __ns3__Hello * SOAP_FMAC4 soap_get___ns3__Hello(struct soap *soap, struct __ns3__Hello *p, const char *tag, const char *type) +{ + if ((p = soap_in___ns3__Hello(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct __ns3__Hello * SOAP_FMAC2 soap_instantiate___ns3__Hello(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate___ns3__Hello(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE___ns3__Hello, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct __ns3__Hello); + if (size) + *size = sizeof(struct __ns3__Hello); + } + else + { cp->ptr = (void*)SOAP_NEW(struct __ns3__Hello[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct __ns3__Hello); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct __ns3__Hello*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__Hello(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct __ns3__Hello %p -> %p\n", q, p)); + *(struct __ns3__Hello*)p = *(struct __ns3__Hello*)q; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default__xop__Include(struct soap *soap, struct _xop__Include *a) +{ + (void)soap; /* appease -Wall -Werror */ + a->__size = 0; + a->__ptr = NULL; + a->id = NULL; + a->type = NULL; + a->options = NULL; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize__xop__Include(struct soap *soap, struct _xop__Include const*a) +{ + if (a->__ptr && !soap_array_reference(soap, a, (struct soap_array*)&a->__ptr, 1, SOAP_TYPE__xop__Include)) + if (a->id || a->type) + soap->mode |= SOAP_ENC_DIME; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__xop__Include(struct soap *soap, const char *tag, int id, const struct _xop__Include *a, const char *type) +{ +#ifndef WITH_LEANER + id = soap_attachment(soap, tag, id, a, (struct soap_array*)&a->__ptr, a->id, a->type, a->options, 1, type, SOAP_TYPE__xop__Include); +#else + id = soap_element_id(soap, tag, id, a, (struct soap_array*)&a->__ptr, 1, type, SOAP_TYPE__xop__Include); +#endif + if (id < 0) + return soap->error; + if (soap_element_begin_out(soap, tag, id, type)) + return soap->error; + if (soap_putbase64(soap, a->__ptr, a->__size)) + return soap->error; + return soap_element_end_out(soap, tag); +} + +SOAP_FMAC3 struct _xop__Include * SOAP_FMAC4 soap_in__xop__Include(struct soap *soap, const char *tag, struct _xop__Include *a, const char *type) +{ + (void)type; /* appease -Wall -Werror */ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (*soap->type && soap_match_tag(soap, soap->type, type) && soap_match_tag(soap, soap->type, ":base64Binary") && soap_match_tag(soap, soap->type, ":base64")) + { soap->error = SOAP_TYPE; + return NULL; + } + a = (struct _xop__Include *)soap_id_enter(soap, soap->id, a, SOAP_TYPE__xop__Include, sizeof(struct _xop__Include), 0, NULL, NULL, NULL); + if (!a) + return NULL; + soap_default__xop__Include(soap, a); + if (soap->body && !*soap->href) + { + a->__ptr = soap_getbase64(soap, &a->__size, 0); +#ifndef WITH_LEANER + if (soap_xop_forward(soap, &a->__ptr, &a->__size, &a->id, &a->type, &a->options)) + return NULL; +#endif + if ((!a->__ptr && soap->error) || soap_element_end_in(soap, tag)) + return NULL; + } + else + { +#ifndef WITH_LEANER + if (*soap->href != '#') + { if (soap_dime_forward(soap, &a->__ptr, &a->__size, &a->id, &a->type, &a->options)) + return NULL; + } + else +#endif + a = (struct _xop__Include *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__xop__Include, 0, sizeof(struct _xop__Include), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put__xop__Include(struct soap *soap, const struct _xop__Include *a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, (struct soap_array*)&a->__ptr, 1, tag, SOAP_TYPE__xop__Include); + if (soap_out__xop__Include(soap, tag?tag:"xop:Include", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct _xop__Include * SOAP_FMAC4 soap_get__xop__Include(struct soap *soap, struct _xop__Include *p, const char *tag, const char *type) +{ + if ((p = soap_in__xop__Include(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC1 struct _xop__Include * SOAP_FMAC2 soap_instantiate__xop__Include(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size) +{ + (void)type; (void)arrayType; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_instantiate__xop__Include(%d, %s, %s)\n", n, type?type:"", arrayType?arrayType:"")); + struct soap_clist *cp = soap_link(soap, NULL, SOAP_TYPE__xop__Include, n, soap_fdelete); + if (!cp) + return NULL; + if (n < 0) + { cp->ptr = (void*)SOAP_NEW(struct _xop__Include); + if (size) + *size = sizeof(struct _xop__Include); + } + else + { cp->ptr = (void*)SOAP_NEW(struct _xop__Include[n]); + if (!cp->ptr) + { soap->error = SOAP_EOM; + return NULL; + } + if (size) + *size = n * sizeof(struct _xop__Include); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Instantiated location=%p\n", cp->ptr)); + return (struct _xop__Include*)cp->ptr; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__xop__Include(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ + (void)soap; (void)st; (void)len; (void)n; /* appease -Wall -Werror */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying struct _xop__Include %p -> %p\n", q, p)); + *(struct _xop__Include*)p = *(struct _xop__Include*)q; +} + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_SOAP_ENV__Reason)) + soap_serialize_SOAP_ENV__Reason(soap, *a); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerToSOAP_ENV__Reason(struct soap *soap, const char *tag, int id, struct SOAP_ENV__Reason *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_SOAP_ENV__Reason); + if (id < 0) + return soap->error; + return soap_out_SOAP_ENV__Reason(soap, tag, id, *a, type); +} + +SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Reason(struct soap *soap, const char *tag, struct SOAP_ENV__Reason **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (struct SOAP_ENV__Reason **)soap_malloc(soap, sizeof(struct SOAP_ENV__Reason *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = soap_in_SOAP_ENV__Reason(soap, tag, *a, type))) + return NULL; + } + else + { a = (struct SOAP_ENV__Reason **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_SOAP_ENV__Reason, sizeof(struct SOAP_ENV__Reason), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Reason); + if (soap_out_PointerToSOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_get_PointerToSOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerToSOAP_ENV__Reason(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +#endif + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_SOAP_ENV__Detail)) + soap_serialize_SOAP_ENV__Detail(soap, *a); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerToSOAP_ENV__Detail(struct soap *soap, const char *tag, int id, struct SOAP_ENV__Detail *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_SOAP_ENV__Detail); + if (id < 0) + return soap->error; + return soap_out_SOAP_ENV__Detail(soap, tag, id, *a, type); +} + +SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Detail(struct soap *soap, const char *tag, struct SOAP_ENV__Detail **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (struct SOAP_ENV__Detail **)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = soap_in_SOAP_ENV__Detail(soap, tag, *a, type))) + return NULL; + } + else + { a = (struct SOAP_ENV__Detail **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_SOAP_ENV__Detail, sizeof(struct SOAP_ENV__Detail), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Detail); + if (soap_out_PointerToSOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_get_PointerToSOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerToSOAP_ENV__Detail(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +#endif + +#ifndef WITH_NOGLOBAL + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_SOAP_ENV__Code)) + soap_serialize_SOAP_ENV__Code(soap, *a); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerToSOAP_ENV__Code(struct soap *soap, const char *tag, int id, struct SOAP_ENV__Code *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_SOAP_ENV__Code); + if (id < 0) + return soap->error; + return soap_out_SOAP_ENV__Code(soap, tag, id, *a, type); +} + +SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Code(struct soap *soap, const char *tag, struct SOAP_ENV__Code **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (struct SOAP_ENV__Code **)soap_malloc(soap, sizeof(struct SOAP_ENV__Code *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = soap_in_SOAP_ENV__Code(soap, tag, *a, type))) + return NULL; + } + else + { a = (struct SOAP_ENV__Code **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_SOAP_ENV__Code, sizeof(struct SOAP_ENV__Code), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Code); + if (soap_out_PointerToSOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_get_PointerToSOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerToSOAP_ENV__Code(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +#endif + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadSymbolResponse(struct soap *soap, _ns1__UploadSymbolResponse *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__UploadSymbolResponse)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadSymbolResponse(struct soap *soap, const char *tag, int id, _ns1__UploadSymbolResponse *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__UploadSymbolResponse); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__UploadSymbolResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadSymbolResponse(struct soap *soap, const char *tag, _ns1__UploadSymbolResponse **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__UploadSymbolResponse **)soap_malloc(soap, sizeof(_ns1__UploadSymbolResponse *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__UploadSymbolResponse *)soap_instantiate__ns1__UploadSymbolResponse(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__UploadSymbolResponse ** p = (_ns1__UploadSymbolResponse **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__UploadSymbolResponse, sizeof(_ns1__UploadSymbolResponse), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadSymbolResponse(struct soap *soap, _ns1__UploadSymbolResponse *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__UploadSymbolResponse); + if (soap_out_PointerTo_ns1__UploadSymbolResponse(soap, tag?tag:"ns1:UploadSymbolResponse", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__UploadSymbolResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadSymbolResponse(struct soap *soap, _ns1__UploadSymbolResponse **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__UploadSymbolResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadSymbol(struct soap *soap, _ns1__UploadSymbol *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__UploadSymbol)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadSymbol(struct soap *soap, const char *tag, int id, _ns1__UploadSymbol *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__UploadSymbol); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__UploadSymbol ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadSymbol(struct soap *soap, const char *tag, _ns1__UploadSymbol **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__UploadSymbol **)soap_malloc(soap, sizeof(_ns1__UploadSymbol *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__UploadSymbol *)soap_instantiate__ns1__UploadSymbol(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__UploadSymbol ** p = (_ns1__UploadSymbol **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__UploadSymbol, sizeof(_ns1__UploadSymbol), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadSymbol(struct soap *soap, _ns1__UploadSymbol *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__UploadSymbol); + if (soap_out_PointerTo_ns1__UploadSymbol(soap, tag?tag:"ns1:UploadSymbol", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__UploadSymbol ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadSymbol(struct soap *soap, _ns1__UploadSymbol **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__UploadSymbol(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap *soap, _ns1__UploadAdditionalInfoResponse *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__UploadAdditionalInfoResponse)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap *soap, const char *tag, int id, _ns1__UploadAdditionalInfoResponse *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__UploadAdditionalInfoResponse); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap *soap, const char *tag, _ns1__UploadAdditionalInfoResponse **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__UploadAdditionalInfoResponse **)soap_malloc(soap, sizeof(_ns1__UploadAdditionalInfoResponse *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__UploadAdditionalInfoResponse *)soap_instantiate__ns1__UploadAdditionalInfoResponse(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__UploadAdditionalInfoResponse ** p = (_ns1__UploadAdditionalInfoResponse **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__UploadAdditionalInfoResponse, sizeof(_ns1__UploadAdditionalInfoResponse), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap *soap, _ns1__UploadAdditionalInfoResponse *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfoResponse); + if (soap_out_PointerTo_ns1__UploadAdditionalInfoResponse(soap, tag?tag:"ns1:UploadAdditionalInfoResponse", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap *soap, _ns1__UploadAdditionalInfoResponse **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__UploadAdditionalInfoResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadAdditionalInfo(struct soap *soap, _ns1__UploadAdditionalInfo *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__UploadAdditionalInfo)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadAdditionalInfo(struct soap *soap, const char *tag, int id, _ns1__UploadAdditionalInfo *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__UploadAdditionalInfo); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfo ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadAdditionalInfo(struct soap *soap, const char *tag, _ns1__UploadAdditionalInfo **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__UploadAdditionalInfo **)soap_malloc(soap, sizeof(_ns1__UploadAdditionalInfo *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__UploadAdditionalInfo *)soap_instantiate__ns1__UploadAdditionalInfo(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__UploadAdditionalInfo ** p = (_ns1__UploadAdditionalInfo **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__UploadAdditionalInfo, sizeof(_ns1__UploadAdditionalInfo), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadAdditionalInfo(struct soap *soap, _ns1__UploadAdditionalInfo *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfo); + if (soap_out_PointerTo_ns1__UploadAdditionalInfo(soap, tag?tag:"ns1:UploadAdditionalInfo", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__UploadAdditionalInfo ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadAdditionalInfo(struct soap *soap, _ns1__UploadAdditionalInfo **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__UploadAdditionalInfo(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadMiniDumpResponse(struct soap *soap, _ns1__UploadMiniDumpResponse *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__UploadMiniDumpResponse)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadMiniDumpResponse(struct soap *soap, const char *tag, int id, _ns1__UploadMiniDumpResponse *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__UploadMiniDumpResponse); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__UploadMiniDumpResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadMiniDumpResponse(struct soap *soap, const char *tag, _ns1__UploadMiniDumpResponse **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__UploadMiniDumpResponse **)soap_malloc(soap, sizeof(_ns1__UploadMiniDumpResponse *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__UploadMiniDumpResponse *)soap_instantiate__ns1__UploadMiniDumpResponse(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__UploadMiniDumpResponse ** p = (_ns1__UploadMiniDumpResponse **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__UploadMiniDumpResponse, sizeof(_ns1__UploadMiniDumpResponse), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadMiniDumpResponse(struct soap *soap, _ns1__UploadMiniDumpResponse *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__UploadMiniDumpResponse); + if (soap_out_PointerTo_ns1__UploadMiniDumpResponse(soap, tag?tag:"ns1:UploadMiniDumpResponse", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__UploadMiniDumpResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadMiniDumpResponse(struct soap *soap, _ns1__UploadMiniDumpResponse **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__UploadMiniDumpResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadMiniDump(struct soap *soap, _ns1__UploadMiniDump *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__UploadMiniDump)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadMiniDump(struct soap *soap, const char *tag, int id, _ns1__UploadMiniDump *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__UploadMiniDump); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__UploadMiniDump ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadMiniDump(struct soap *soap, const char *tag, _ns1__UploadMiniDump **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__UploadMiniDump **)soap_malloc(soap, sizeof(_ns1__UploadMiniDump *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__UploadMiniDump *)soap_instantiate__ns1__UploadMiniDump(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__UploadMiniDump ** p = (_ns1__UploadMiniDump **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__UploadMiniDump, sizeof(_ns1__UploadMiniDump), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadMiniDump(struct soap *soap, _ns1__UploadMiniDump *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__UploadMiniDump); + if (soap_out_PointerTo_ns1__UploadMiniDump(soap, tag?tag:"ns1:UploadMiniDump", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__UploadMiniDump ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadMiniDump(struct soap *soap, _ns1__UploadMiniDump **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__UploadMiniDump(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__HelloResponse(struct soap *soap, _ns1__HelloResponse *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__HelloResponse)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__HelloResponse(struct soap *soap, const char *tag, int id, _ns1__HelloResponse *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__HelloResponse); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__HelloResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__HelloResponse(struct soap *soap, const char *tag, _ns1__HelloResponse **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__HelloResponse **)soap_malloc(soap, sizeof(_ns1__HelloResponse *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__HelloResponse *)soap_instantiate__ns1__HelloResponse(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__HelloResponse ** p = (_ns1__HelloResponse **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__HelloResponse, sizeof(_ns1__HelloResponse), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__HelloResponse(struct soap *soap, _ns1__HelloResponse *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__HelloResponse); + if (soap_out_PointerTo_ns1__HelloResponse(soap, tag?tag:"ns1:HelloResponse", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__HelloResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__HelloResponse(struct soap *soap, _ns1__HelloResponse **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__HelloResponse(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__Hello(struct soap *soap, _ns1__Hello *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE__ns1__Hello)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__Hello(struct soap *soap, const char *tag, int id, _ns1__Hello *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE__ns1__Hello); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 _ns1__Hello ** SOAP_FMAC4 soap_in_PointerTo_ns1__Hello(struct soap *soap, const char *tag, _ns1__Hello **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (_ns1__Hello **)soap_malloc(soap, sizeof(_ns1__Hello *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (_ns1__Hello *)soap_instantiate__ns1__Hello(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { _ns1__Hello ** p = (_ns1__Hello **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__ns1__Hello, sizeof(_ns1__Hello), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__Hello(struct soap *soap, _ns1__Hello *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_ns1__Hello); + if (soap_out_PointerTo_ns1__Hello(soap, tag?tag:"ns1:Hello", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 _ns1__Hello ** SOAP_FMAC4 soap_get_PointerTo_ns1__Hello(struct soap *soap, _ns1__Hello **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_ns1__Hello(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__Response(struct soap *soap, ns1__Response *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_ns1__Response)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__Response(struct soap *soap, const char *tag, int id, ns1__Response *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_ns1__Response); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 ns1__Response ** SOAP_FMAC4 soap_in_PointerTons1__Response(struct soap *soap, const char *tag, ns1__Response **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (ns1__Response **)soap_malloc(soap, sizeof(ns1__Response *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (ns1__Response *)soap_instantiate_ns1__Response(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { ns1__Response ** p = (ns1__Response **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_ns1__Response, sizeof(ns1__Response), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__Response(struct soap *soap, ns1__Response *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTons1__Response); + if (soap_out_PointerTons1__Response(soap, tag?tag:"ns1:Response", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 ns1__Response ** SOAP_FMAC4 soap_get_PointerTons1__Response(struct soap *soap, ns1__Response **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTons1__Response(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__Application(struct soap *soap, ns1__Application *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_ns1__Application)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__Application(struct soap *soap, const char *tag, int id, ns1__Application *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_ns1__Application); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 ns1__Application ** SOAP_FMAC4 soap_in_PointerTons1__Application(struct soap *soap, const char *tag, ns1__Application **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (ns1__Application **)soap_malloc(soap, sizeof(ns1__Application *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (ns1__Application *)soap_instantiate_ns1__Application(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { ns1__Application ** p = (ns1__Application **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_ns1__Application, sizeof(ns1__Application), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__Application(struct soap *soap, ns1__Application *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTons1__Application); + if (soap_out_PointerTons1__Application(soap, tag?tag:"ns1:Application", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 ns1__Application ** SOAP_FMAC4 soap_get_PointerTons1__Application(struct soap *soap, ns1__Application **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTons1__Application(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__ClientLib(struct soap *soap, ns1__ClientLib *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_ns1__ClientLib)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__ClientLib(struct soap *soap, const char *tag, int id, ns1__ClientLib *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_ns1__ClientLib); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 ns1__ClientLib ** SOAP_FMAC4 soap_in_PointerTons1__ClientLib(struct soap *soap, const char *tag, ns1__ClientLib **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (ns1__ClientLib **)soap_malloc(soap, sizeof(ns1__ClientLib *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (ns1__ClientLib *)soap_instantiate_ns1__ClientLib(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { ns1__ClientLib ** p = (ns1__ClientLib **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_ns1__ClientLib, sizeof(ns1__ClientLib), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__ClientLib(struct soap *soap, ns1__ClientLib *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTons1__ClientLib); + if (soap_out_PointerTons1__ClientLib(soap, tag?tag:"ns1:ClientLib", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 ns1__ClientLib ** SOAP_FMAC4 soap_get_PointerTons1__ClientLib(struct soap *soap, ns1__ClientLib **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTons1__ClientLib(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_xop__Include(struct soap *soap, struct _xop__Include *const*a) +{ + if (*a) + soap_serialize__xop__Include(soap, *a); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_xop__Include(struct soap *soap, const char *tag, int id, struct _xop__Include *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, (struct soap_array*)&(*a)->__ptr, 1, type, SOAP_TYPE__xop__Include); + if (id < 0) + return soap->error; + return soap_out__xop__Include(soap, tag, id, *a, type); +} + +SOAP_FMAC3 struct _xop__Include ** SOAP_FMAC4 soap_in_PointerTo_xop__Include(struct soap *soap, const char *tag, struct _xop__Include **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (struct _xop__Include **)soap_malloc(soap, sizeof(struct _xop__Include *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = soap_in__xop__Include(soap, tag, *a, type))) + return NULL; + } + else + { a = (struct _xop__Include **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE__xop__Include, sizeof(struct _xop__Include), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_xop__Include(struct soap *soap, struct _xop__Include *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTo_xop__Include); + if (soap_out_PointerTo_xop__Include(soap, tag?tag:"xop:Include", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 struct _xop__Include ** SOAP_FMAC4 soap_get_PointerTo_xop__Include(struct soap *soap, struct _xop__Include **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTo_xop__Include(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__Solution(struct soap *soap, ns1__Solution *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_ns1__Solution)) + (*a)->soap_serialize(soap); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__Solution(struct soap *soap, const char *tag, int id, ns1__Solution *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_ns1__Solution); + if (id < 0) + return soap->error; + return (*a)->soap_out(soap, tag, id, type); +} + +SOAP_FMAC3 ns1__Solution ** SOAP_FMAC4 soap_in_PointerTons1__Solution(struct soap *soap, const char *tag, ns1__Solution **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (ns1__Solution **)soap_malloc(soap, sizeof(ns1__Solution *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = (ns1__Solution *)soap_instantiate_ns1__Solution(soap, -1, soap->type, soap->arrayType, NULL))) + return NULL; + (*a)->soap_default(soap); + if (!(*a)->soap_in(soap, tag, NULL)) + return NULL; + } + else + { ns1__Solution ** p = (ns1__Solution **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_ns1__Solution, sizeof(ns1__Solution), 0); + a = p; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__Solution(struct soap *soap, ns1__Solution *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTons1__Solution); + if (soap_out_PointerTons1__Solution(soap, tag?tag:"ns1:Solution", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 ns1__Solution ** SOAP_FMAC4 soap_get_PointerTons1__Solution(struct soap *soap, ns1__Solution **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTons1__Solution(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTostd__wstring(struct soap *soap, std::wstring *const*a) +{ + if (!soap_reference(soap, *a, SOAP_TYPE_std__wstring)) + soap_serialize_std__wstring(soap, *a); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTostd__wstring(struct soap *soap, const char *tag, int id, std::wstring *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_std__wstring); + if (id < 0) + return soap->error; + return soap_out_std__wstring(soap, tag, id, *a, type); +} + +SOAP_FMAC3 std::wstring ** SOAP_FMAC4 soap_in_PointerTostd__wstring(struct soap *soap, const char *tag, std::wstring **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (std::wstring **)soap_malloc(soap, sizeof(std::wstring *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = soap_in_std__wstring(soap, tag, *a, type))) + return NULL; + } + else + { a = (std::wstring **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_std__wstring, sizeof(std::wstring), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTostd__wstring(struct soap *soap, std::wstring *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTostd__wstring); + if (soap_out_PointerTostd__wstring(soap, tag?tag:"string", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 std::wstring ** SOAP_FMAC4 soap_get_PointerTostd__wstring(struct soap *soap, std::wstring **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTostd__wstring(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTounsignedByte(struct soap *soap, unsigned char *const*a) +{ + soap_reference(soap, *a, SOAP_TYPE_unsignedByte); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTounsignedByte(struct soap *soap, const char *tag, int id, unsigned char *const*a, const char *type) +{ + id = soap_element_id(soap, tag, id, *a, NULL, 0, type, SOAP_TYPE_unsignedByte); + if (id < 0) + return soap->error; + return soap_out_unsignedByte(soap, tag, id, *a, type); +} + +SOAP_FMAC3 unsigned char ** SOAP_FMAC4 soap_in_PointerTounsignedByte(struct soap *soap, const char *tag, unsigned char **a, const char *type) +{ + if (soap_element_begin_in(soap, tag, 1, NULL)) + return NULL; + if (!a) + if (!(a = (unsigned char **)soap_malloc(soap, sizeof(unsigned char *)))) + return NULL; + *a = NULL; + if (!soap->null && *soap->href != '#') + { soap_revert(soap); + if (!(*a = soap_in_unsignedByte(soap, tag, *a, type))) + return NULL; + } + else + { a = (unsigned char **)soap_id_lookup(soap, soap->href, (void**)a, SOAP_TYPE_unsignedByte, sizeof(unsigned char), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + } + return a; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTounsignedByte(struct soap *soap, unsigned char *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerTounsignedByte); + if (soap_out_PointerTounsignedByte(soap, tag?tag:"unsignedByte", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 unsigned char ** SOAP_FMAC4 soap_get_PointerTounsignedByte(struct soap *soap, unsigned char **p, const char *tag, const char *type) +{ + if ((p = soap_in_PointerTounsignedByte(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__QName(struct soap *soap, const char *tag, int id, char *const*a, const char *type) +{ + return soap_outstring(soap, tag, id, a, type, SOAP_TYPE__QName); +} + +SOAP_FMAC3 char * * SOAP_FMAC4 soap_in__QName(struct soap *soap, const char *tag, char **a, const char *type) +{ char **p; + p = soap_instring(soap, tag, a, type, SOAP_TYPE__QName, 2, -1, -1); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put__QName(struct soap *soap, char *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE__QName); + if (soap_out__QName(soap, tag?tag:"byte", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 char ** SOAP_FMAC4 soap_get__QName(struct soap *soap, char **p, const char *tag, const char *type) +{ + if ((p = soap_in__QName(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_default_string(struct soap *soap, char **a) +{ + (void)soap; /* appease -Wall -Werror */ +#ifdef SOAP_DEFAULT_string + *a = SOAP_DEFAULT_string; +#else + *a = (char *)0; +#endif +} + +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_string(struct soap *soap, char *const*a) +{ + soap_reference(soap, *a, SOAP_TYPE_string); +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_string(struct soap *soap, const char *tag, int id, char *const*a, const char *type) +{ + return soap_outstring(soap, tag, id, a, type, SOAP_TYPE_string); +} + +SOAP_FMAC3 char * * SOAP_FMAC4 soap_in_string(struct soap *soap, const char *tag, char **a, const char *type) +{ char **p; + p = soap_instring(soap, tag, a, type, SOAP_TYPE_string, 1, -1, -1); + return p; +} + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_string(struct soap *soap, char *const*a, const char *tag, const char *type) +{ + register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_string); + if (soap_out_string(soap, tag?tag:"byte", id, a, type)) + return soap->error; + return soap_putindependent(soap); +} + +SOAP_FMAC3 char ** SOAP_FMAC4 soap_get_string(struct soap *soap, char **p, const char *tag, const char *type) +{ + if ((p = soap_in_string(soap, tag, p, type))) + if (soap_getindependent(soap)) + return NULL; + return p; +} + +#if defined(__BORLANDC__) +#pragma option pop +#pragma option pop +#endif + +/* End of soapC.cpp */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapH.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapH.h new file mode 100644 index 000000000..82c714987 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapH.h @@ -0,0 +1,1479 @@ +/* soapH.h + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#ifndef soapH_H +#define soapH_H +#include "soapStub.h" +#ifndef WITH_NOIDREF + +#ifdef __cplusplus +extern "C" { +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap*, const void*, int); +SOAP_FMAC3 int SOAP_FMAC4 soap_putelement(struct soap*, const void*, const char*, int, int); +SOAP_FMAC3 void *SOAP_FMAC4 soap_getelement(struct soap*, int*); + +#ifdef __cplusplus +} +#endif +SOAP_FMAC3 int SOAP_FMAC4 soap_putindependent(struct soap*); +SOAP_FMAC3 int SOAP_FMAC4 soap_getindependent(struct soap*); +#endif +SOAP_FMAC3 int SOAP_FMAC4 soap_ignore_element(struct soap*); + +SOAP_FMAC3 void * SOAP_FMAC4 soap_instantiate(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 int SOAP_FMAC4 soap_fdelete(struct soap_clist*); +SOAP_FMAC3 void* SOAP_FMAC4 soap_class_id_enter(struct soap*, const char*, void*, int, size_t, const char*, const char*); + +SOAP_FMAC3 void* SOAP_FMAC4 soap_container_id_forward(struct soap*, const char*, void*, size_t, int, int, size_t, unsigned int); + +SOAP_FMAC3 void SOAP_FMAC4 soap_container_insert(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE_byte +#define SOAP_TYPE_byte (3) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_byte(struct soap*, char *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_byte(struct soap*, const char*, int, const char *, const char*); +SOAP_FMAC3 char * SOAP_FMAC4 soap_in_byte(struct soap*, const char*, char *, const char*); + +#ifndef soap_write_byte +#define soap_write_byte(soap, data) ( soap_begin_send(soap) || soap_put_byte(soap, data, "byte", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_byte(struct soap*, const char *, const char*, const char*); + +#ifndef soap_read_byte +#define soap_read_byte(soap, data) ( soap_begin_recv(soap) || !soap_get_byte(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 char * SOAP_FMAC4 soap_get_byte(struct soap*, char *, const char*, const char*); + +#ifndef SOAP_TYPE_short +#define SOAP_TYPE_short (30) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_short(struct soap*, short *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_short(struct soap*, const char*, int, const short *, const char*); +SOAP_FMAC3 short * SOAP_FMAC4 soap_in_short(struct soap*, const char*, short *, const char*); + +#ifndef soap_write_short +#define soap_write_short(soap, data) ( soap_begin_send(soap) || soap_put_short(soap, data, "short", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_short(struct soap*, const short *, const char*, const char*); + +#ifndef soap_read_short +#define soap_read_short(soap, data) ( soap_begin_recv(soap) || !soap_get_short(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 short * SOAP_FMAC4 soap_get_short(struct soap*, short *, const char*, const char*); + +#ifndef SOAP_TYPE_int +#define SOAP_TYPE_int (1) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_int(struct soap*, int *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_int(struct soap*, const char*, int, const int *, const char*); +SOAP_FMAC3 int * SOAP_FMAC4 soap_in_int(struct soap*, const char*, int *, const char*); + +#ifndef soap_write_int +#define soap_write_int(soap, data) ( soap_begin_send(soap) || soap_put_int(soap, data, "int", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_int(struct soap*, const int *, const char*, const char*); + +#ifndef soap_read_int +#define soap_read_int(soap, data) ( soap_begin_recv(soap) || !soap_get_int(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 int * SOAP_FMAC4 soap_get_int(struct soap*, int *, const char*, const char*); + +#ifndef SOAP_TYPE_unsignedByte +#define SOAP_TYPE_unsignedByte (10) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_unsignedByte(struct soap*, unsigned char *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_unsignedByte(struct soap*, const char*, int, const unsigned char *, const char*); +SOAP_FMAC3 unsigned char * SOAP_FMAC4 soap_in_unsignedByte(struct soap*, const char*, unsigned char *, const char*); + +#ifndef soap_write_unsignedByte +#define soap_write_unsignedByte(soap, data) ( soap_begin_send(soap) || soap_put_unsignedByte(soap, data, "unsignedByte", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_unsignedByte(struct soap*, const unsigned char *, const char*, const char*); + +#ifndef soap_read_unsignedByte +#define soap_read_unsignedByte(soap, data) ( soap_begin_recv(soap) || !soap_get_unsignedByte(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 unsigned char * SOAP_FMAC4 soap_get_unsignedByte(struct soap*, unsigned char *, const char*, const char*); + +#ifndef SOAP_TYPE_unsignedShort +#define SOAP_TYPE_unsignedShort (31) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_unsignedShort(struct soap*, unsigned short *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_unsignedShort(struct soap*, const char*, int, const unsigned short *, const char*); +SOAP_FMAC3 unsigned short * SOAP_FMAC4 soap_in_unsignedShort(struct soap*, const char*, unsigned short *, const char*); + +#ifndef soap_write_unsignedShort +#define soap_write_unsignedShort(soap, data) ( soap_begin_send(soap) || soap_put_unsignedShort(soap, data, "unsignedShort", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_unsignedShort(struct soap*, const unsigned short *, const char*, const char*); + +#ifndef soap_read_unsignedShort +#define soap_read_unsignedShort(soap, data) ( soap_begin_recv(soap) || !soap_get_unsignedShort(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 unsigned short * SOAP_FMAC4 soap_get_unsignedShort(struct soap*, unsigned short *, const char*, const char*); + +#ifndef SOAP_TYPE_unsignedInt +#define SOAP_TYPE_unsignedInt (9) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_unsignedInt(struct soap*, unsigned int *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_unsignedInt(struct soap*, const char*, int, const unsigned int *, const char*); +SOAP_FMAC3 unsigned int * SOAP_FMAC4 soap_in_unsignedInt(struct soap*, const char*, unsigned int *, const char*); + +#ifndef soap_write_unsignedInt +#define soap_write_unsignedInt(soap, data) ( soap_begin_send(soap) || soap_put_unsignedInt(soap, data, "unsignedInt", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_unsignedInt(struct soap*, const unsigned int *, const char*, const char*); + +#ifndef soap_read_unsignedInt +#define soap_read_unsignedInt(soap, data) ( soap_begin_recv(soap) || !soap_get_unsignedInt(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 unsigned int * SOAP_FMAC4 soap_get_unsignedInt(struct soap*, unsigned int *, const char*, const char*); + +#ifndef SOAP_TYPE_bool +#define SOAP_TYPE_bool (36) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_bool(struct soap*, bool *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_bool(struct soap*, const char*, int, const bool *, const char*); + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_bool2s(struct soap*, bool); +SOAP_FMAC3 bool * SOAP_FMAC4 soap_in_bool(struct soap*, const char*, bool *, const char*); + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2bool(struct soap*, const char*, bool *); + +#ifndef soap_write_bool +#define soap_write_bool(soap, data) ( soap_begin_send(soap) || soap_put_bool(soap, data, "boolean", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_bool(struct soap*, const bool *, const char*, const char*); + +#ifndef soap_read_bool +#define soap_read_bool(soap, data) ( soap_begin_recv(soap) || !soap_get_bool(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 bool * SOAP_FMAC4 soap_get_bool(struct soap*, bool *, const char*, const char*); + +#ifndef SOAP_TYPE_ns1__AdditionalInfoType +#define SOAP_TYPE_ns1__AdditionalInfoType (27) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__AdditionalInfoType(struct soap*, enum ns1__AdditionalInfoType *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__AdditionalInfoType(struct soap*, const char*, int, const enum ns1__AdditionalInfoType *, const char*); + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__AdditionalInfoType2s(struct soap*, enum ns1__AdditionalInfoType); +SOAP_FMAC3 enum ns1__AdditionalInfoType * SOAP_FMAC4 soap_in_ns1__AdditionalInfoType(struct soap*, const char*, enum ns1__AdditionalInfoType *, const char*); + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__AdditionalInfoType(struct soap*, const char*, enum ns1__AdditionalInfoType *); + +#ifndef soap_write_ns1__AdditionalInfoType +#define soap_write_ns1__AdditionalInfoType(soap, data) ( soap_begin_send(soap) || soap_put_ns1__AdditionalInfoType(soap, data, "ns1:AdditionalInfoType", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__AdditionalInfoType(struct soap*, const enum ns1__AdditionalInfoType *, const char*, const char*); + +#ifndef soap_read_ns1__AdditionalInfoType +#define soap_read_ns1__AdditionalInfoType(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__AdditionalInfoType(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 enum ns1__AdditionalInfoType * SOAP_FMAC4 soap_get_ns1__AdditionalInfoType(struct soap*, enum ns1__AdditionalInfoType *, const char*, const char*); + +#ifndef SOAP_TYPE_ns1__SolutionType +#define SOAP_TYPE_ns1__SolutionType (26) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__SolutionType(struct soap*, enum ns1__SolutionType *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__SolutionType(struct soap*, const char*, int, const enum ns1__SolutionType *, const char*); + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__SolutionType2s(struct soap*, enum ns1__SolutionType); +SOAP_FMAC3 enum ns1__SolutionType * SOAP_FMAC4 soap_in_ns1__SolutionType(struct soap*, const char*, enum ns1__SolutionType *, const char*); + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__SolutionType(struct soap*, const char*, enum ns1__SolutionType *); + +#ifndef soap_write_ns1__SolutionType +#define soap_write_ns1__SolutionType(soap, data) ( soap_begin_send(soap) || soap_put_ns1__SolutionType(soap, data, "ns1:SolutionType", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__SolutionType(struct soap*, const enum ns1__SolutionType *, const char*, const char*); + +#ifndef soap_read_ns1__SolutionType +#define soap_read_ns1__SolutionType(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__SolutionType(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 enum ns1__SolutionType * SOAP_FMAC4 soap_get_ns1__SolutionType(struct soap*, enum ns1__SolutionType *, const char*, const char*); + +#ifndef SOAP_TYPE_ns1__ResponseType +#define SOAP_TYPE_ns1__ResponseType (25) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__ResponseType(struct soap*, enum ns1__ResponseType *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__ResponseType(struct soap*, const char*, int, const enum ns1__ResponseType *, const char*); + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__ResponseType2s(struct soap*, enum ns1__ResponseType); +SOAP_FMAC3 enum ns1__ResponseType * SOAP_FMAC4 soap_in_ns1__ResponseType(struct soap*, const char*, enum ns1__ResponseType *, const char*); + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__ResponseType(struct soap*, const char*, enum ns1__ResponseType *); + +#ifndef soap_write_ns1__ResponseType +#define soap_write_ns1__ResponseType(soap, data) ( soap_begin_send(soap) || soap_put_ns1__ResponseType(soap, data, "ns1:ResponseType", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__ResponseType(struct soap*, const enum ns1__ResponseType *, const char*, const char*); + +#ifndef soap_read_ns1__ResponseType +#define soap_read_ns1__ResponseType(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__ResponseType(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 enum ns1__ResponseType * SOAP_FMAC4 soap_get_ns1__ResponseType(struct soap*, enum ns1__ResponseType *, const char*, const char*); + +#ifndef SOAP_TYPE_ns1__Architecture +#define SOAP_TYPE_ns1__Architecture (24) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__Architecture(struct soap*, enum ns1__Architecture *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Architecture(struct soap*, const char*, int, const enum ns1__Architecture *, const char*); + +SOAP_FMAC3S const char* SOAP_FMAC4S soap_ns1__Architecture2s(struct soap*, enum ns1__Architecture); +SOAP_FMAC3 enum ns1__Architecture * SOAP_FMAC4 soap_in_ns1__Architecture(struct soap*, const char*, enum ns1__Architecture *, const char*); + +SOAP_FMAC3S int SOAP_FMAC4S soap_s2ns1__Architecture(struct soap*, const char*, enum ns1__Architecture *); + +#ifndef soap_write_ns1__Architecture +#define soap_write_ns1__Architecture(soap, data) ( soap_begin_send(soap) || soap_put_ns1__Architecture(soap, data, "ns1:Architecture", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__Architecture(struct soap*, const enum ns1__Architecture *, const char*, const char*); + +#ifndef soap_read_ns1__Architecture +#define soap_read_ns1__Architecture(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__Architecture(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 enum ns1__Architecture * SOAP_FMAC4 soap_get_ns1__Architecture(struct soap*, enum ns1__Architecture *, const char*, const char*); + +#ifndef SOAP_TYPE_ns2__guid +#define SOAP_TYPE_ns2__guid (29) +#endif + +#define soap_default_ns2__guid(soap, a) soap_default_std__wstring(soap, a) + + +#define soap_serialize_ns2__guid(soap, a) soap_serialize_std__wstring(soap, a) + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns2__guid(struct soap*, const char*, int, const std::wstring*, const char*); +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_in_ns2__guid(struct soap*, const char*, std::wstring*, const char*); + +#ifndef soap_write_ns2__guid +#define soap_write_ns2__guid(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns2:guid", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns2__guid(struct soap*, const std::wstring *, const char*, const char*); + +#ifndef soap_read_ns2__guid +#define soap_read_ns2__guid(soap, data) ( soap_begin_recv(soap) || !soap_get_ns2__guid(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_get_ns2__guid(struct soap*, std::wstring *, const char*, const char*); + +#define soap_new_ns2__guid(soap, n) soap_instantiate_ns2__guid(soap, n, NULL, NULL, NULL) + + +#define soap_delete_ns2__guid(soap, p) soap_delete(soap, p) + + +#define soap_instantiate_ns2__guid soap_instantiate_std__wstring + + +#define soap_copy_ns2__guid soap_copy_std__wstring + +#ifndef SOAP_TYPE_std__wstring +#define SOAP_TYPE_std__wstring (28) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_std__wstring(struct soap*, std::wstring *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_std__wstring(struct soap*, const std::wstring *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_std__wstring(struct soap*, const char*, int, const std::wstring*, const char*); +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_in_std__wstring(struct soap*, const char*, std::wstring*, const char*); + +#ifndef soap_write_std__wstring +#define soap_write_std__wstring(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "string", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_std__wstring(struct soap*, const std::wstring *, const char*, const char*); + +#ifndef soap_read_std__wstring +#define soap_read_std__wstring(soap, data) ( soap_begin_recv(soap) || !soap_get_std__wstring(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_get_std__wstring(struct soap*, std::wstring *, const char*, const char*); + +#define soap_new_std__wstring(soap, n) soap_instantiate_std__wstring(soap, n, NULL, NULL, NULL) + + +#define soap_delete_std__wstring(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 std::wstring * SOAP_FMAC2 soap_instantiate_std__wstring(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_std__wstring(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__UploadSymbolResponse +#define SOAP_TYPE__ns1__UploadSymbolResponse (23) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadSymbolResponse(struct soap*, const char*, int, const _ns1__UploadSymbolResponse *, const char*); +SOAP_FMAC3 _ns1__UploadSymbolResponse * SOAP_FMAC4 soap_in__ns1__UploadSymbolResponse(struct soap*, const char*, _ns1__UploadSymbolResponse *, const char*); + +#ifndef soap_write__ns1__UploadSymbolResponse +#define soap_write__ns1__UploadSymbolResponse(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:UploadSymbolResponse", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__UploadSymbolResponse +#define soap_read__ns1__UploadSymbolResponse(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__UploadSymbolResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadSymbolResponse * SOAP_FMAC4 soap_get__ns1__UploadSymbolResponse(struct soap*, _ns1__UploadSymbolResponse *, const char*, const char*); + +#define soap_new__ns1__UploadSymbolResponse(soap, n) soap_instantiate__ns1__UploadSymbolResponse(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__UploadSymbolResponse(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__UploadSymbolResponse * SOAP_FMAC2 soap_instantiate__ns1__UploadSymbolResponse(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadSymbolResponse(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__UploadSymbol +#define SOAP_TYPE__ns1__UploadSymbol (22) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadSymbol(struct soap*, const char*, int, const _ns1__UploadSymbol *, const char*); +SOAP_FMAC3 _ns1__UploadSymbol * SOAP_FMAC4 soap_in__ns1__UploadSymbol(struct soap*, const char*, _ns1__UploadSymbol *, const char*); + +#ifndef soap_write__ns1__UploadSymbol +#define soap_write__ns1__UploadSymbol(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:UploadSymbol", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__UploadSymbol +#define soap_read__ns1__UploadSymbol(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__UploadSymbol(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadSymbol * SOAP_FMAC4 soap_get__ns1__UploadSymbol(struct soap*, _ns1__UploadSymbol *, const char*, const char*); + +#define soap_new__ns1__UploadSymbol(soap, n) soap_instantiate__ns1__UploadSymbol(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__UploadSymbol(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__UploadSymbol * SOAP_FMAC2 soap_instantiate__ns1__UploadSymbol(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadSymbol(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__UploadAdditionalInfoResponse +#define SOAP_TYPE__ns1__UploadAdditionalInfoResponse (21) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadAdditionalInfoResponse(struct soap*, const char*, int, const _ns1__UploadAdditionalInfoResponse *, const char*); +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse * SOAP_FMAC4 soap_in__ns1__UploadAdditionalInfoResponse(struct soap*, const char*, _ns1__UploadAdditionalInfoResponse *, const char*); + +#ifndef soap_write__ns1__UploadAdditionalInfoResponse +#define soap_write__ns1__UploadAdditionalInfoResponse(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:UploadAdditionalInfoResponse", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__UploadAdditionalInfoResponse +#define soap_read__ns1__UploadAdditionalInfoResponse(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__UploadAdditionalInfoResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse * SOAP_FMAC4 soap_get__ns1__UploadAdditionalInfoResponse(struct soap*, _ns1__UploadAdditionalInfoResponse *, const char*, const char*); + +#define soap_new__ns1__UploadAdditionalInfoResponse(soap, n) soap_instantiate__ns1__UploadAdditionalInfoResponse(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__UploadAdditionalInfoResponse(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__UploadAdditionalInfoResponse * SOAP_FMAC2 soap_instantiate__ns1__UploadAdditionalInfoResponse(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadAdditionalInfoResponse(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__UploadAdditionalInfo +#define SOAP_TYPE__ns1__UploadAdditionalInfo (20) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadAdditionalInfo(struct soap*, const char*, int, const _ns1__UploadAdditionalInfo *, const char*); +SOAP_FMAC3 _ns1__UploadAdditionalInfo * SOAP_FMAC4 soap_in__ns1__UploadAdditionalInfo(struct soap*, const char*, _ns1__UploadAdditionalInfo *, const char*); + +#ifndef soap_write__ns1__UploadAdditionalInfo +#define soap_write__ns1__UploadAdditionalInfo(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:UploadAdditionalInfo", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__UploadAdditionalInfo +#define soap_read__ns1__UploadAdditionalInfo(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__UploadAdditionalInfo(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadAdditionalInfo * SOAP_FMAC4 soap_get__ns1__UploadAdditionalInfo(struct soap*, _ns1__UploadAdditionalInfo *, const char*, const char*); + +#define soap_new__ns1__UploadAdditionalInfo(soap, n) soap_instantiate__ns1__UploadAdditionalInfo(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__UploadAdditionalInfo(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__UploadAdditionalInfo * SOAP_FMAC2 soap_instantiate__ns1__UploadAdditionalInfo(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadAdditionalInfo(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__UploadMiniDumpResponse +#define SOAP_TYPE__ns1__UploadMiniDumpResponse (19) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadMiniDumpResponse(struct soap*, const char*, int, const _ns1__UploadMiniDumpResponse *, const char*); +SOAP_FMAC3 _ns1__UploadMiniDumpResponse * SOAP_FMAC4 soap_in__ns1__UploadMiniDumpResponse(struct soap*, const char*, _ns1__UploadMiniDumpResponse *, const char*); + +#ifndef soap_write__ns1__UploadMiniDumpResponse +#define soap_write__ns1__UploadMiniDumpResponse(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:UploadMiniDumpResponse", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__UploadMiniDumpResponse +#define soap_read__ns1__UploadMiniDumpResponse(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__UploadMiniDumpResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadMiniDumpResponse * SOAP_FMAC4 soap_get__ns1__UploadMiniDumpResponse(struct soap*, _ns1__UploadMiniDumpResponse *, const char*, const char*); + +#define soap_new__ns1__UploadMiniDumpResponse(soap, n) soap_instantiate__ns1__UploadMiniDumpResponse(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__UploadMiniDumpResponse(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__UploadMiniDumpResponse * SOAP_FMAC2 soap_instantiate__ns1__UploadMiniDumpResponse(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadMiniDumpResponse(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__UploadMiniDump +#define SOAP_TYPE__ns1__UploadMiniDump (18) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__UploadMiniDump(struct soap*, const char*, int, const _ns1__UploadMiniDump *, const char*); +SOAP_FMAC3 _ns1__UploadMiniDump * SOAP_FMAC4 soap_in__ns1__UploadMiniDump(struct soap*, const char*, _ns1__UploadMiniDump *, const char*); + +#ifndef soap_write__ns1__UploadMiniDump +#define soap_write__ns1__UploadMiniDump(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:UploadMiniDump", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__UploadMiniDump +#define soap_read__ns1__UploadMiniDump(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__UploadMiniDump(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadMiniDump * SOAP_FMAC4 soap_get__ns1__UploadMiniDump(struct soap*, _ns1__UploadMiniDump *, const char*, const char*); + +#define soap_new__ns1__UploadMiniDump(soap, n) soap_instantiate__ns1__UploadMiniDump(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__UploadMiniDump(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__UploadMiniDump * SOAP_FMAC2 soap_instantiate__ns1__UploadMiniDump(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__UploadMiniDump(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__HelloResponse +#define SOAP_TYPE__ns1__HelloResponse (17) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__HelloResponse(struct soap*, const char*, int, const _ns1__HelloResponse *, const char*); +SOAP_FMAC3 _ns1__HelloResponse * SOAP_FMAC4 soap_in__ns1__HelloResponse(struct soap*, const char*, _ns1__HelloResponse *, const char*); + +#ifndef soap_write__ns1__HelloResponse +#define soap_write__ns1__HelloResponse(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:HelloResponse", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__HelloResponse +#define soap_read__ns1__HelloResponse(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__HelloResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__HelloResponse * SOAP_FMAC4 soap_get__ns1__HelloResponse(struct soap*, _ns1__HelloResponse *, const char*, const char*); + +#define soap_new__ns1__HelloResponse(soap, n) soap_instantiate__ns1__HelloResponse(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__HelloResponse(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__HelloResponse * SOAP_FMAC2 soap_instantiate__ns1__HelloResponse(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__HelloResponse(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__ns1__Hello +#define SOAP_TYPE__ns1__Hello (16) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__ns1__Hello(struct soap*, const char*, int, const _ns1__Hello *, const char*); +SOAP_FMAC3 _ns1__Hello * SOAP_FMAC4 soap_in__ns1__Hello(struct soap*, const char*, _ns1__Hello *, const char*); + +#ifndef soap_write__ns1__Hello +#define soap_write__ns1__Hello(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:Hello", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read__ns1__Hello +#define soap_read__ns1__Hello(soap, data) ( soap_begin_recv(soap) || !soap_get__ns1__Hello(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__Hello * SOAP_FMAC4 soap_get__ns1__Hello(struct soap*, _ns1__Hello *, const char*, const char*); + +#define soap_new__ns1__Hello(soap, n) soap_instantiate__ns1__Hello(soap, n, NULL, NULL, NULL) + + +#define soap_delete__ns1__Hello(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 _ns1__Hello * SOAP_FMAC2 soap_instantiate__ns1__Hello(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__ns1__Hello(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE_ns1__Solution +#define SOAP_TYPE_ns1__Solution (15) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Solution(struct soap*, const char*, int, const ns1__Solution *, const char*); +SOAP_FMAC3 ns1__Solution * SOAP_FMAC4 soap_in_ns1__Solution(struct soap*, const char*, ns1__Solution *, const char*); + +#ifndef soap_write_ns1__Solution +#define soap_write_ns1__Solution(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:Solution", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read_ns1__Solution +#define soap_read_ns1__Solution(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__Solution(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__Solution * SOAP_FMAC4 soap_get_ns1__Solution(struct soap*, ns1__Solution *, const char*, const char*); + +#define soap_new_ns1__Solution(soap, n) soap_instantiate_ns1__Solution(soap, n, NULL, NULL, NULL) + + +#define soap_delete_ns1__Solution(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 ns1__Solution * SOAP_FMAC2 soap_instantiate_ns1__Solution(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__Solution(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE_ns1__Response +#define SOAP_TYPE_ns1__Response (14) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Response(struct soap*, const char*, int, const ns1__Response *, const char*); +SOAP_FMAC3 ns1__Response * SOAP_FMAC4 soap_in_ns1__Response(struct soap*, const char*, ns1__Response *, const char*); + +#ifndef soap_write_ns1__Response +#define soap_write_ns1__Response(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:Response", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read_ns1__Response +#define soap_read_ns1__Response(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__Response(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__Response * SOAP_FMAC4 soap_get_ns1__Response(struct soap*, ns1__Response *, const char*, const char*); + +#define soap_new_ns1__Response(soap, n) soap_instantiate_ns1__Response(soap, n, NULL, NULL, NULL) + + +#define soap_delete_ns1__Response(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 ns1__Response * SOAP_FMAC2 soap_instantiate_ns1__Response(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__Response(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE_ns1__Application +#define SOAP_TYPE_ns1__Application (13) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__Application(struct soap*, const char*, int, const ns1__Application *, const char*); +SOAP_FMAC3 ns1__Application * SOAP_FMAC4 soap_in_ns1__Application(struct soap*, const char*, ns1__Application *, const char*); + +#ifndef soap_write_ns1__Application +#define soap_write_ns1__Application(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:Application", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read_ns1__Application +#define soap_read_ns1__Application(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__Application(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__Application * SOAP_FMAC4 soap_get_ns1__Application(struct soap*, ns1__Application *, const char*, const char*); + +#define soap_new_ns1__Application(soap, n) soap_instantiate_ns1__Application(soap, n, NULL, NULL, NULL) + + +#define soap_delete_ns1__Application(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 ns1__Application * SOAP_FMAC2 soap_instantiate_ns1__Application(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__Application(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE_ns1__ClientLib +#define SOAP_TYPE_ns1__ClientLib (12) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__ClientLib(struct soap*, const char*, int, const ns1__ClientLib *, const char*); +SOAP_FMAC3 ns1__ClientLib * SOAP_FMAC4 soap_in_ns1__ClientLib(struct soap*, const char*, ns1__ClientLib *, const char*); + +#ifndef soap_write_ns1__ClientLib +#define soap_write_ns1__ClientLib(soap, data) ( soap_begin_send(soap) || ((data)->soap_serialize(soap), 0) || (data)->soap_put(soap, "ns1:ClientLib", NULL) || soap_end_send(soap) ) +#endif + + +#ifndef soap_read_ns1__ClientLib +#define soap_read_ns1__ClientLib(soap, data) ( soap_begin_recv(soap) || !soap_get_ns1__ClientLib(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__ClientLib * SOAP_FMAC4 soap_get_ns1__ClientLib(struct soap*, ns1__ClientLib *, const char*, const char*); + +#define soap_new_ns1__ClientLib(soap, n) soap_instantiate_ns1__ClientLib(soap, n, NULL, NULL, NULL) + + +#define soap_delete_ns1__ClientLib(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 ns1__ClientLib * SOAP_FMAC2 soap_instantiate_ns1__ClientLib(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_ns1__ClientLib(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_SOAP_ENV__Fault +#define SOAP_TYPE_SOAP_ENV__Fault (71) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Fault(struct soap*, struct SOAP_ENV__Fault *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Fault(struct soap*, const struct SOAP_ENV__Fault *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Fault(struct soap*, const char*, int, const struct SOAP_ENV__Fault *, const char*); +SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_in_SOAP_ENV__Fault(struct soap*, const char*, struct SOAP_ENV__Fault *, const char*); + +#ifndef soap_write_SOAP_ENV__Fault +#define soap_write_SOAP_ENV__Fault(soap, data) ( soap_begin_send(soap) || (soap_serialize_SOAP_ENV__Fault(soap, data), 0) || soap_put_SOAP_ENV__Fault(soap, data, "SOAP-ENV:Fault", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Fault(struct soap*, const struct SOAP_ENV__Fault *, const char*, const char*); + +#ifndef soap_read_SOAP_ENV__Fault +#define soap_read_SOAP_ENV__Fault(soap, data) ( soap_begin_recv(soap) || !soap_get_SOAP_ENV__Fault(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_get_SOAP_ENV__Fault(struct soap*, struct SOAP_ENV__Fault *, const char*, const char*); + +#define soap_new_SOAP_ENV__Fault(soap, n) soap_instantiate_SOAP_ENV__Fault(soap, n, NULL, NULL, NULL) + + +#define soap_delete_SOAP_ENV__Fault(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct SOAP_ENV__Fault * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Fault(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Fault(struct soap*, int, int, void*, size_t, const void*, size_t); + +#endif + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_SOAP_ENV__Reason +#define SOAP_TYPE_SOAP_ENV__Reason (70) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Reason(struct soap*, const struct SOAP_ENV__Reason *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Reason(struct soap*, const char*, int, const struct SOAP_ENV__Reason *, const char*); +SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_in_SOAP_ENV__Reason(struct soap*, const char*, struct SOAP_ENV__Reason *, const char*); + +#ifndef soap_write_SOAP_ENV__Reason +#define soap_write_SOAP_ENV__Reason(soap, data) ( soap_begin_send(soap) || (soap_serialize_SOAP_ENV__Reason(soap, data), 0) || soap_put_SOAP_ENV__Reason(soap, data, "SOAP-ENV:Reason", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Reason(struct soap*, const struct SOAP_ENV__Reason *, const char*, const char*); + +#ifndef soap_read_SOAP_ENV__Reason +#define soap_read_SOAP_ENV__Reason(soap, data) ( soap_begin_recv(soap) || !soap_get_SOAP_ENV__Reason(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_get_SOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason *, const char*, const char*); + +#define soap_new_SOAP_ENV__Reason(soap, n) soap_instantiate_SOAP_ENV__Reason(soap, n, NULL, NULL, NULL) + + +#define soap_delete_SOAP_ENV__Reason(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct SOAP_ENV__Reason * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Reason(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Reason(struct soap*, int, int, void*, size_t, const void*, size_t); + +#endif + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_SOAP_ENV__Detail +#define SOAP_TYPE_SOAP_ENV__Detail (67) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Detail(struct soap*, const struct SOAP_ENV__Detail *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Detail(struct soap*, const char*, int, const struct SOAP_ENV__Detail *, const char*); +SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_in_SOAP_ENV__Detail(struct soap*, const char*, struct SOAP_ENV__Detail *, const char*); + +#ifndef soap_write_SOAP_ENV__Detail +#define soap_write_SOAP_ENV__Detail(soap, data) ( soap_begin_send(soap) || (soap_serialize_SOAP_ENV__Detail(soap, data), 0) || soap_put_SOAP_ENV__Detail(soap, data, "SOAP-ENV:Detail", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Detail(struct soap*, const struct SOAP_ENV__Detail *, const char*, const char*); + +#ifndef soap_read_SOAP_ENV__Detail +#define soap_read_SOAP_ENV__Detail(soap, data) ( soap_begin_recv(soap) || !soap_get_SOAP_ENV__Detail(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_get_SOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail *, const char*, const char*); + +#define soap_new_SOAP_ENV__Detail(soap, n) soap_instantiate_SOAP_ENV__Detail(soap, n, NULL, NULL, NULL) + + +#define soap_delete_SOAP_ENV__Detail(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct SOAP_ENV__Detail * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Detail(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Detail(struct soap*, int, int, void*, size_t, const void*, size_t); + +#endif + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_SOAP_ENV__Code +#define SOAP_TYPE_SOAP_ENV__Code (65) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Code(struct soap*, const struct SOAP_ENV__Code *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Code(struct soap*, const char*, int, const struct SOAP_ENV__Code *, const char*); +SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_in_SOAP_ENV__Code(struct soap*, const char*, struct SOAP_ENV__Code *, const char*); + +#ifndef soap_write_SOAP_ENV__Code +#define soap_write_SOAP_ENV__Code(soap, data) ( soap_begin_send(soap) || (soap_serialize_SOAP_ENV__Code(soap, data), 0) || soap_put_SOAP_ENV__Code(soap, data, "SOAP-ENV:Code", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Code(struct soap*, const struct SOAP_ENV__Code *, const char*, const char*); + +#ifndef soap_read_SOAP_ENV__Code +#define soap_read_SOAP_ENV__Code(soap, data) ( soap_begin_recv(soap) || !soap_get_SOAP_ENV__Code(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_get_SOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code *, const char*, const char*); + +#define soap_new_SOAP_ENV__Code(soap, n) soap_instantiate_SOAP_ENV__Code(soap, n, NULL, NULL, NULL) + + +#define soap_delete_SOAP_ENV__Code(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct SOAP_ENV__Code * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Code(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Code(struct soap*, int, int, void*, size_t, const void*, size_t); + +#endif + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_SOAP_ENV__Header +#define SOAP_TYPE_SOAP_ENV__Header (64) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Header(struct soap*, struct SOAP_ENV__Header *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_SOAP_ENV__Header(struct soap*, const struct SOAP_ENV__Header *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Header(struct soap*, const char*, int, const struct SOAP_ENV__Header *, const char*); +SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_in_SOAP_ENV__Header(struct soap*, const char*, struct SOAP_ENV__Header *, const char*); + +#ifndef soap_write_SOAP_ENV__Header +#define soap_write_SOAP_ENV__Header(soap, data) ( soap_begin_send(soap) || (soap_serialize_SOAP_ENV__Header(soap, data), 0) || soap_put_SOAP_ENV__Header(soap, data, "SOAP-ENV:Header", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Header(struct soap*, const struct SOAP_ENV__Header *, const char*, const char*); + +#ifndef soap_read_SOAP_ENV__Header +#define soap_read_SOAP_ENV__Header(soap, data) ( soap_begin_recv(soap) || !soap_get_SOAP_ENV__Header(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_get_SOAP_ENV__Header(struct soap*, struct SOAP_ENV__Header *, const char*, const char*); + +#define soap_new_SOAP_ENV__Header(soap, n) soap_instantiate_SOAP_ENV__Header(soap, n, NULL, NULL, NULL) + + +#define soap_delete_SOAP_ENV__Header(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct SOAP_ENV__Header * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Header(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy_SOAP_ENV__Header(struct soap*, int, int, void*, size_t, const void*, size_t); + +#endif + +#ifndef SOAP_TYPE___ns4__UploadSymbol +#define SOAP_TYPE___ns4__UploadSymbol (63) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__UploadSymbol(struct soap*, struct __ns4__UploadSymbol *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__UploadSymbol(struct soap*, const struct __ns4__UploadSymbol *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__UploadSymbol(struct soap*, const char*, int, const struct __ns4__UploadSymbol *, const char*); +SOAP_FMAC3 struct __ns4__UploadSymbol * SOAP_FMAC4 soap_in___ns4__UploadSymbol(struct soap*, const char*, struct __ns4__UploadSymbol *, const char*); + +#ifndef soap_write___ns4__UploadSymbol +#define soap_write___ns4__UploadSymbol(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns4__UploadSymbol(soap, data), 0) || soap_put___ns4__UploadSymbol(soap, data, "-ns4:UploadSymbol", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__UploadSymbol(struct soap*, const struct __ns4__UploadSymbol *, const char*, const char*); + +#ifndef soap_read___ns4__UploadSymbol +#define soap_read___ns4__UploadSymbol(soap, data) ( soap_begin_recv(soap) || !soap_get___ns4__UploadSymbol(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns4__UploadSymbol * SOAP_FMAC4 soap_get___ns4__UploadSymbol(struct soap*, struct __ns4__UploadSymbol *, const char*, const char*); + +#define soap_new___ns4__UploadSymbol(soap, n) soap_instantiate___ns4__UploadSymbol(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns4__UploadSymbol(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns4__UploadSymbol * SOAP_FMAC2 soap_instantiate___ns4__UploadSymbol(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__UploadSymbol(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns4__UploadAdditionalInfo +#define SOAP_TYPE___ns4__UploadAdditionalInfo (61) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__UploadAdditionalInfo(struct soap*, struct __ns4__UploadAdditionalInfo *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__UploadAdditionalInfo(struct soap*, const struct __ns4__UploadAdditionalInfo *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__UploadAdditionalInfo(struct soap*, const char*, int, const struct __ns4__UploadAdditionalInfo *, const char*); +SOAP_FMAC3 struct __ns4__UploadAdditionalInfo * SOAP_FMAC4 soap_in___ns4__UploadAdditionalInfo(struct soap*, const char*, struct __ns4__UploadAdditionalInfo *, const char*); + +#ifndef soap_write___ns4__UploadAdditionalInfo +#define soap_write___ns4__UploadAdditionalInfo(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns4__UploadAdditionalInfo(soap, data), 0) || soap_put___ns4__UploadAdditionalInfo(soap, data, "-ns4:UploadAdditionalInfo", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__UploadAdditionalInfo(struct soap*, const struct __ns4__UploadAdditionalInfo *, const char*, const char*); + +#ifndef soap_read___ns4__UploadAdditionalInfo +#define soap_read___ns4__UploadAdditionalInfo(soap, data) ( soap_begin_recv(soap) || !soap_get___ns4__UploadAdditionalInfo(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns4__UploadAdditionalInfo * SOAP_FMAC4 soap_get___ns4__UploadAdditionalInfo(struct soap*, struct __ns4__UploadAdditionalInfo *, const char*, const char*); + +#define soap_new___ns4__UploadAdditionalInfo(soap, n) soap_instantiate___ns4__UploadAdditionalInfo(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns4__UploadAdditionalInfo(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns4__UploadAdditionalInfo * SOAP_FMAC2 soap_instantiate___ns4__UploadAdditionalInfo(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__UploadAdditionalInfo(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns4__UploadMiniDump +#define SOAP_TYPE___ns4__UploadMiniDump (59) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__UploadMiniDump(struct soap*, struct __ns4__UploadMiniDump *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__UploadMiniDump(struct soap*, const struct __ns4__UploadMiniDump *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__UploadMiniDump(struct soap*, const char*, int, const struct __ns4__UploadMiniDump *, const char*); +SOAP_FMAC3 struct __ns4__UploadMiniDump * SOAP_FMAC4 soap_in___ns4__UploadMiniDump(struct soap*, const char*, struct __ns4__UploadMiniDump *, const char*); + +#ifndef soap_write___ns4__UploadMiniDump +#define soap_write___ns4__UploadMiniDump(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns4__UploadMiniDump(soap, data), 0) || soap_put___ns4__UploadMiniDump(soap, data, "-ns4:UploadMiniDump", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__UploadMiniDump(struct soap*, const struct __ns4__UploadMiniDump *, const char*, const char*); + +#ifndef soap_read___ns4__UploadMiniDump +#define soap_read___ns4__UploadMiniDump(soap, data) ( soap_begin_recv(soap) || !soap_get___ns4__UploadMiniDump(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns4__UploadMiniDump * SOAP_FMAC4 soap_get___ns4__UploadMiniDump(struct soap*, struct __ns4__UploadMiniDump *, const char*, const char*); + +#define soap_new___ns4__UploadMiniDump(soap, n) soap_instantiate___ns4__UploadMiniDump(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns4__UploadMiniDump(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns4__UploadMiniDump * SOAP_FMAC2 soap_instantiate___ns4__UploadMiniDump(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__UploadMiniDump(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns4__Hello +#define SOAP_TYPE___ns4__Hello (57) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns4__Hello(struct soap*, struct __ns4__Hello *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns4__Hello(struct soap*, const struct __ns4__Hello *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns4__Hello(struct soap*, const char*, int, const struct __ns4__Hello *, const char*); +SOAP_FMAC3 struct __ns4__Hello * SOAP_FMAC4 soap_in___ns4__Hello(struct soap*, const char*, struct __ns4__Hello *, const char*); + +#ifndef soap_write___ns4__Hello +#define soap_write___ns4__Hello(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns4__Hello(soap, data), 0) || soap_put___ns4__Hello(soap, data, "-ns4:Hello", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns4__Hello(struct soap*, const struct __ns4__Hello *, const char*, const char*); + +#ifndef soap_read___ns4__Hello +#define soap_read___ns4__Hello(soap, data) ( soap_begin_recv(soap) || !soap_get___ns4__Hello(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns4__Hello * SOAP_FMAC4 soap_get___ns4__Hello(struct soap*, struct __ns4__Hello *, const char*, const char*); + +#define soap_new___ns4__Hello(soap, n) soap_instantiate___ns4__Hello(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns4__Hello(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns4__Hello * SOAP_FMAC2 soap_instantiate___ns4__Hello(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns4__Hello(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns3__UploadSymbol +#define SOAP_TYPE___ns3__UploadSymbol (55) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__UploadSymbol(struct soap*, struct __ns3__UploadSymbol *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__UploadSymbol(struct soap*, const struct __ns3__UploadSymbol *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__UploadSymbol(struct soap*, const char*, int, const struct __ns3__UploadSymbol *, const char*); +SOAP_FMAC3 struct __ns3__UploadSymbol * SOAP_FMAC4 soap_in___ns3__UploadSymbol(struct soap*, const char*, struct __ns3__UploadSymbol *, const char*); + +#ifndef soap_write___ns3__UploadSymbol +#define soap_write___ns3__UploadSymbol(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns3__UploadSymbol(soap, data), 0) || soap_put___ns3__UploadSymbol(soap, data, "-ns3:UploadSymbol", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__UploadSymbol(struct soap*, const struct __ns3__UploadSymbol *, const char*, const char*); + +#ifndef soap_read___ns3__UploadSymbol +#define soap_read___ns3__UploadSymbol(soap, data) ( soap_begin_recv(soap) || !soap_get___ns3__UploadSymbol(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns3__UploadSymbol * SOAP_FMAC4 soap_get___ns3__UploadSymbol(struct soap*, struct __ns3__UploadSymbol *, const char*, const char*); + +#define soap_new___ns3__UploadSymbol(soap, n) soap_instantiate___ns3__UploadSymbol(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns3__UploadSymbol(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns3__UploadSymbol * SOAP_FMAC2 soap_instantiate___ns3__UploadSymbol(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__UploadSymbol(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns3__UploadAdditionalInfo +#define SOAP_TYPE___ns3__UploadAdditionalInfo (51) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__UploadAdditionalInfo(struct soap*, struct __ns3__UploadAdditionalInfo *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__UploadAdditionalInfo(struct soap*, const struct __ns3__UploadAdditionalInfo *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__UploadAdditionalInfo(struct soap*, const char*, int, const struct __ns3__UploadAdditionalInfo *, const char*); +SOAP_FMAC3 struct __ns3__UploadAdditionalInfo * SOAP_FMAC4 soap_in___ns3__UploadAdditionalInfo(struct soap*, const char*, struct __ns3__UploadAdditionalInfo *, const char*); + +#ifndef soap_write___ns3__UploadAdditionalInfo +#define soap_write___ns3__UploadAdditionalInfo(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns3__UploadAdditionalInfo(soap, data), 0) || soap_put___ns3__UploadAdditionalInfo(soap, data, "-ns3:UploadAdditionalInfo", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__UploadAdditionalInfo(struct soap*, const struct __ns3__UploadAdditionalInfo *, const char*, const char*); + +#ifndef soap_read___ns3__UploadAdditionalInfo +#define soap_read___ns3__UploadAdditionalInfo(soap, data) ( soap_begin_recv(soap) || !soap_get___ns3__UploadAdditionalInfo(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns3__UploadAdditionalInfo * SOAP_FMAC4 soap_get___ns3__UploadAdditionalInfo(struct soap*, struct __ns3__UploadAdditionalInfo *, const char*, const char*); + +#define soap_new___ns3__UploadAdditionalInfo(soap, n) soap_instantiate___ns3__UploadAdditionalInfo(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns3__UploadAdditionalInfo(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns3__UploadAdditionalInfo * SOAP_FMAC2 soap_instantiate___ns3__UploadAdditionalInfo(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__UploadAdditionalInfo(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns3__UploadMiniDump +#define SOAP_TYPE___ns3__UploadMiniDump (47) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__UploadMiniDump(struct soap*, struct __ns3__UploadMiniDump *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__UploadMiniDump(struct soap*, const struct __ns3__UploadMiniDump *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__UploadMiniDump(struct soap*, const char*, int, const struct __ns3__UploadMiniDump *, const char*); +SOAP_FMAC3 struct __ns3__UploadMiniDump * SOAP_FMAC4 soap_in___ns3__UploadMiniDump(struct soap*, const char*, struct __ns3__UploadMiniDump *, const char*); + +#ifndef soap_write___ns3__UploadMiniDump +#define soap_write___ns3__UploadMiniDump(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns3__UploadMiniDump(soap, data), 0) || soap_put___ns3__UploadMiniDump(soap, data, "-ns3:UploadMiniDump", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__UploadMiniDump(struct soap*, const struct __ns3__UploadMiniDump *, const char*, const char*); + +#ifndef soap_read___ns3__UploadMiniDump +#define soap_read___ns3__UploadMiniDump(soap, data) ( soap_begin_recv(soap) || !soap_get___ns3__UploadMiniDump(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns3__UploadMiniDump * SOAP_FMAC4 soap_get___ns3__UploadMiniDump(struct soap*, struct __ns3__UploadMiniDump *, const char*, const char*); + +#define soap_new___ns3__UploadMiniDump(soap, n) soap_instantiate___ns3__UploadMiniDump(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns3__UploadMiniDump(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns3__UploadMiniDump * SOAP_FMAC2 soap_instantiate___ns3__UploadMiniDump(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__UploadMiniDump(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE___ns3__Hello +#define SOAP_TYPE___ns3__Hello (43) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default___ns3__Hello(struct soap*, struct __ns3__Hello *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize___ns3__Hello(struct soap*, const struct __ns3__Hello *); +SOAP_FMAC3 int SOAP_FMAC4 soap_out___ns3__Hello(struct soap*, const char*, int, const struct __ns3__Hello *, const char*); +SOAP_FMAC3 struct __ns3__Hello * SOAP_FMAC4 soap_in___ns3__Hello(struct soap*, const char*, struct __ns3__Hello *, const char*); + +#ifndef soap_write___ns3__Hello +#define soap_write___ns3__Hello(soap, data) ( soap_begin_send(soap) || (soap_serialize___ns3__Hello(soap, data), 0) || soap_put___ns3__Hello(soap, data, "-ns3:Hello", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns3__Hello(struct soap*, const struct __ns3__Hello *, const char*, const char*); + +#ifndef soap_read___ns3__Hello +#define soap_read___ns3__Hello(soap, data) ( soap_begin_recv(soap) || !soap_get___ns3__Hello(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct __ns3__Hello * SOAP_FMAC4 soap_get___ns3__Hello(struct soap*, struct __ns3__Hello *, const char*, const char*); + +#define soap_new___ns3__Hello(soap, n) soap_instantiate___ns3__Hello(soap, n, NULL, NULL, NULL) + + +#define soap_delete___ns3__Hello(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct __ns3__Hello * SOAP_FMAC2 soap_instantiate___ns3__Hello(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy___ns3__Hello(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef SOAP_TYPE__xop__Include +#define SOAP_TYPE__xop__Include (8) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default__xop__Include(struct soap*, struct _xop__Include *); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize__xop__Include(struct soap*, struct _xop__Include const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out__xop__Include(struct soap*, const char*, int, const struct _xop__Include *, const char*); +SOAP_FMAC3 struct _xop__Include * SOAP_FMAC4 soap_in__xop__Include(struct soap*, const char*, struct _xop__Include *, const char*); + +#ifndef soap_write__xop__Include +#define soap_write__xop__Include(soap, data) ( soap_begin_send(soap) || (soap_serialize__xop__Include(soap, data), 0) || soap_put__xop__Include(soap, data, "xop:Include", NULL) || soap_end_send(soap) ) +#endif + + +SOAP_FMAC3 int SOAP_FMAC4 soap_put__xop__Include(struct soap*, const struct _xop__Include *, const char*, const char*); + +#ifndef soap_read__xop__Include +#define soap_read__xop__Include(soap, data) ( soap_begin_recv(soap) || !soap_get__xop__Include(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct _xop__Include * SOAP_FMAC4 soap_get__xop__Include(struct soap*, struct _xop__Include *, const char*, const char*); + +#define soap_new__xop__Include(soap, n) soap_instantiate__xop__Include(soap, n, NULL, NULL, NULL) + + +#define soap_delete__xop__Include(soap, p) soap_delete(soap, p) + +SOAP_FMAC1 struct _xop__Include * SOAP_FMAC2 soap_instantiate__xop__Include(struct soap*, int, const char*, const char*, size_t*); +SOAP_FMAC3 void SOAP_FMAC4 soap_copy__xop__Include(struct soap*, int, int, void*, size_t, const void*, size_t); + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_PointerToSOAP_ENV__Reason +#define SOAP_TYPE_PointerToSOAP_ENV__Reason (73) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerToSOAP_ENV__Reason(struct soap*, const char *, int, struct SOAP_ENV__Reason *const*, const char *); +SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Reason(struct soap*, const char*, struct SOAP_ENV__Reason **, const char*); + +#ifndef soap_write_PointerToSOAP_ENV__Reason +#define soap_write_PointerToSOAP_ENV__Reason(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerToSOAP_ENV__Reason(soap, data), 0) || soap_put_PointerToSOAP_ENV__Reason(soap, data, "SOAP-ENV:Reason", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason *const*, const char*, const char*); + +#ifndef soap_read_PointerToSOAP_ENV__Reason +#define soap_read_PointerToSOAP_ENV__Reason(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerToSOAP_ENV__Reason(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_get_PointerToSOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason **, const char*, const char*); + +#endif + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_PointerToSOAP_ENV__Detail +#define SOAP_TYPE_PointerToSOAP_ENV__Detail (72) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerToSOAP_ENV__Detail(struct soap*, const char *, int, struct SOAP_ENV__Detail *const*, const char *); +SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Detail(struct soap*, const char*, struct SOAP_ENV__Detail **, const char*); + +#ifndef soap_write_PointerToSOAP_ENV__Detail +#define soap_write_PointerToSOAP_ENV__Detail(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerToSOAP_ENV__Detail(soap, data), 0) || soap_put_PointerToSOAP_ENV__Detail(soap, data, "SOAP-ENV:Detail", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail *const*, const char*, const char*); + +#ifndef soap_read_PointerToSOAP_ENV__Detail +#define soap_read_PointerToSOAP_ENV__Detail(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerToSOAP_ENV__Detail(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_get_PointerToSOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail **, const char*, const char*); + +#endif + +#ifndef WITH_NOGLOBAL + +#ifndef SOAP_TYPE_PointerToSOAP_ENV__Code +#define SOAP_TYPE_PointerToSOAP_ENV__Code (66) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerToSOAP_ENV__Code(struct soap*, const char *, int, struct SOAP_ENV__Code *const*, const char *); +SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Code(struct soap*, const char*, struct SOAP_ENV__Code **, const char*); + +#ifndef soap_write_PointerToSOAP_ENV__Code +#define soap_write_PointerToSOAP_ENV__Code(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerToSOAP_ENV__Code(soap, data), 0) || soap_put_PointerToSOAP_ENV__Code(soap, data, "SOAP-ENV:Code", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code *const*, const char*, const char*); + +#ifndef soap_read_PointerToSOAP_ENV__Code +#define soap_read_PointerToSOAP_ENV__Code(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerToSOAP_ENV__Code(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_get_PointerToSOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code **, const char*, const char*); + +#endif + +#ifndef SOAP_TYPE_PointerTo_ns1__UploadSymbolResponse +#define SOAP_TYPE_PointerTo_ns1__UploadSymbolResponse (53) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadSymbolResponse(struct soap*, _ns1__UploadSymbolResponse *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadSymbolResponse(struct soap*, const char *, int, _ns1__UploadSymbolResponse *const*, const char *); +SOAP_FMAC3 _ns1__UploadSymbolResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadSymbolResponse(struct soap*, const char*, _ns1__UploadSymbolResponse **, const char*); + +#ifndef soap_write_PointerTo_ns1__UploadSymbolResponse +#define soap_write_PointerTo_ns1__UploadSymbolResponse(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__UploadSymbolResponse(soap, data), 0) || soap_put_PointerTo_ns1__UploadSymbolResponse(soap, data, "ns1:UploadSymbolResponse", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadSymbolResponse(struct soap*, _ns1__UploadSymbolResponse *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__UploadSymbolResponse +#define soap_read_PointerTo_ns1__UploadSymbolResponse(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__UploadSymbolResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadSymbolResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadSymbolResponse(struct soap*, _ns1__UploadSymbolResponse **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__UploadSymbol +#define SOAP_TYPE_PointerTo_ns1__UploadSymbol (52) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadSymbol(struct soap*, _ns1__UploadSymbol *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadSymbol(struct soap*, const char *, int, _ns1__UploadSymbol *const*, const char *); +SOAP_FMAC3 _ns1__UploadSymbol ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadSymbol(struct soap*, const char*, _ns1__UploadSymbol **, const char*); + +#ifndef soap_write_PointerTo_ns1__UploadSymbol +#define soap_write_PointerTo_ns1__UploadSymbol(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__UploadSymbol(soap, data), 0) || soap_put_PointerTo_ns1__UploadSymbol(soap, data, "ns1:UploadSymbol", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadSymbol(struct soap*, _ns1__UploadSymbol *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__UploadSymbol +#define soap_read_PointerTo_ns1__UploadSymbol(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__UploadSymbol(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadSymbol ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadSymbol(struct soap*, _ns1__UploadSymbol **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfoResponse +#define SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfoResponse (49) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap*, _ns1__UploadAdditionalInfoResponse *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap*, const char *, int, _ns1__UploadAdditionalInfoResponse *const*, const char *); +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap*, const char*, _ns1__UploadAdditionalInfoResponse **, const char*); + +#ifndef soap_write_PointerTo_ns1__UploadAdditionalInfoResponse +#define soap_write_PointerTo_ns1__UploadAdditionalInfoResponse(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__UploadAdditionalInfoResponse(soap, data), 0) || soap_put_PointerTo_ns1__UploadAdditionalInfoResponse(soap, data, "ns1:UploadAdditionalInfoResponse", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap*, _ns1__UploadAdditionalInfoResponse *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__UploadAdditionalInfoResponse +#define soap_read_PointerTo_ns1__UploadAdditionalInfoResponse(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__UploadAdditionalInfoResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadAdditionalInfoResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadAdditionalInfoResponse(struct soap*, _ns1__UploadAdditionalInfoResponse **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfo +#define SOAP_TYPE_PointerTo_ns1__UploadAdditionalInfo (48) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadAdditionalInfo(struct soap*, _ns1__UploadAdditionalInfo *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadAdditionalInfo(struct soap*, const char *, int, _ns1__UploadAdditionalInfo *const*, const char *); +SOAP_FMAC3 _ns1__UploadAdditionalInfo ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadAdditionalInfo(struct soap*, const char*, _ns1__UploadAdditionalInfo **, const char*); + +#ifndef soap_write_PointerTo_ns1__UploadAdditionalInfo +#define soap_write_PointerTo_ns1__UploadAdditionalInfo(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__UploadAdditionalInfo(soap, data), 0) || soap_put_PointerTo_ns1__UploadAdditionalInfo(soap, data, "ns1:UploadAdditionalInfo", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadAdditionalInfo(struct soap*, _ns1__UploadAdditionalInfo *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__UploadAdditionalInfo +#define soap_read_PointerTo_ns1__UploadAdditionalInfo(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__UploadAdditionalInfo(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadAdditionalInfo ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadAdditionalInfo(struct soap*, _ns1__UploadAdditionalInfo **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__UploadMiniDumpResponse +#define SOAP_TYPE_PointerTo_ns1__UploadMiniDumpResponse (45) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadMiniDumpResponse(struct soap*, _ns1__UploadMiniDumpResponse *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadMiniDumpResponse(struct soap*, const char *, int, _ns1__UploadMiniDumpResponse *const*, const char *); +SOAP_FMAC3 _ns1__UploadMiniDumpResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadMiniDumpResponse(struct soap*, const char*, _ns1__UploadMiniDumpResponse **, const char*); + +#ifndef soap_write_PointerTo_ns1__UploadMiniDumpResponse +#define soap_write_PointerTo_ns1__UploadMiniDumpResponse(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__UploadMiniDumpResponse(soap, data), 0) || soap_put_PointerTo_ns1__UploadMiniDumpResponse(soap, data, "ns1:UploadMiniDumpResponse", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadMiniDumpResponse(struct soap*, _ns1__UploadMiniDumpResponse *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__UploadMiniDumpResponse +#define soap_read_PointerTo_ns1__UploadMiniDumpResponse(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__UploadMiniDumpResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadMiniDumpResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadMiniDumpResponse(struct soap*, _ns1__UploadMiniDumpResponse **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__UploadMiniDump +#define SOAP_TYPE_PointerTo_ns1__UploadMiniDump (44) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__UploadMiniDump(struct soap*, _ns1__UploadMiniDump *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__UploadMiniDump(struct soap*, const char *, int, _ns1__UploadMiniDump *const*, const char *); +SOAP_FMAC3 _ns1__UploadMiniDump ** SOAP_FMAC4 soap_in_PointerTo_ns1__UploadMiniDump(struct soap*, const char*, _ns1__UploadMiniDump **, const char*); + +#ifndef soap_write_PointerTo_ns1__UploadMiniDump +#define soap_write_PointerTo_ns1__UploadMiniDump(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__UploadMiniDump(soap, data), 0) || soap_put_PointerTo_ns1__UploadMiniDump(soap, data, "ns1:UploadMiniDump", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__UploadMiniDump(struct soap*, _ns1__UploadMiniDump *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__UploadMiniDump +#define soap_read_PointerTo_ns1__UploadMiniDump(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__UploadMiniDump(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__UploadMiniDump ** SOAP_FMAC4 soap_get_PointerTo_ns1__UploadMiniDump(struct soap*, _ns1__UploadMiniDump **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__HelloResponse +#define SOAP_TYPE_PointerTo_ns1__HelloResponse (41) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__HelloResponse(struct soap*, _ns1__HelloResponse *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__HelloResponse(struct soap*, const char *, int, _ns1__HelloResponse *const*, const char *); +SOAP_FMAC3 _ns1__HelloResponse ** SOAP_FMAC4 soap_in_PointerTo_ns1__HelloResponse(struct soap*, const char*, _ns1__HelloResponse **, const char*); + +#ifndef soap_write_PointerTo_ns1__HelloResponse +#define soap_write_PointerTo_ns1__HelloResponse(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__HelloResponse(soap, data), 0) || soap_put_PointerTo_ns1__HelloResponse(soap, data, "ns1:HelloResponse", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__HelloResponse(struct soap*, _ns1__HelloResponse *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__HelloResponse +#define soap_read_PointerTo_ns1__HelloResponse(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__HelloResponse(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__HelloResponse ** SOAP_FMAC4 soap_get_PointerTo_ns1__HelloResponse(struct soap*, _ns1__HelloResponse **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_ns1__Hello +#define SOAP_TYPE_PointerTo_ns1__Hello (40) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_ns1__Hello(struct soap*, _ns1__Hello *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_ns1__Hello(struct soap*, const char *, int, _ns1__Hello *const*, const char *); +SOAP_FMAC3 _ns1__Hello ** SOAP_FMAC4 soap_in_PointerTo_ns1__Hello(struct soap*, const char*, _ns1__Hello **, const char*); + +#ifndef soap_write_PointerTo_ns1__Hello +#define soap_write_PointerTo_ns1__Hello(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_ns1__Hello(soap, data), 0) || soap_put_PointerTo_ns1__Hello(soap, data, "ns1:Hello", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_ns1__Hello(struct soap*, _ns1__Hello *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_ns1__Hello +#define soap_read_PointerTo_ns1__Hello(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_ns1__Hello(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 _ns1__Hello ** SOAP_FMAC4 soap_get_PointerTo_ns1__Hello(struct soap*, _ns1__Hello **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTons1__Response +#define SOAP_TYPE_PointerTons1__Response (39) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__Response(struct soap*, ns1__Response *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__Response(struct soap*, const char *, int, ns1__Response *const*, const char *); +SOAP_FMAC3 ns1__Response ** SOAP_FMAC4 soap_in_PointerTons1__Response(struct soap*, const char*, ns1__Response **, const char*); + +#ifndef soap_write_PointerTons1__Response +#define soap_write_PointerTons1__Response(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTons1__Response(soap, data), 0) || soap_put_PointerTons1__Response(soap, data, "ns1:Response", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__Response(struct soap*, ns1__Response *const*, const char*, const char*); + +#ifndef soap_read_PointerTons1__Response +#define soap_read_PointerTons1__Response(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTons1__Response(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__Response ** SOAP_FMAC4 soap_get_PointerTons1__Response(struct soap*, ns1__Response **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTons1__Application +#define SOAP_TYPE_PointerTons1__Application (38) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__Application(struct soap*, ns1__Application *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__Application(struct soap*, const char *, int, ns1__Application *const*, const char *); +SOAP_FMAC3 ns1__Application ** SOAP_FMAC4 soap_in_PointerTons1__Application(struct soap*, const char*, ns1__Application **, const char*); + +#ifndef soap_write_PointerTons1__Application +#define soap_write_PointerTons1__Application(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTons1__Application(soap, data), 0) || soap_put_PointerTons1__Application(soap, data, "ns1:Application", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__Application(struct soap*, ns1__Application *const*, const char*, const char*); + +#ifndef soap_read_PointerTons1__Application +#define soap_read_PointerTons1__Application(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTons1__Application(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__Application ** SOAP_FMAC4 soap_get_PointerTons1__Application(struct soap*, ns1__Application **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTons1__ClientLib +#define SOAP_TYPE_PointerTons1__ClientLib (37) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__ClientLib(struct soap*, ns1__ClientLib *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__ClientLib(struct soap*, const char *, int, ns1__ClientLib *const*, const char *); +SOAP_FMAC3 ns1__ClientLib ** SOAP_FMAC4 soap_in_PointerTons1__ClientLib(struct soap*, const char*, ns1__ClientLib **, const char*); + +#ifndef soap_write_PointerTons1__ClientLib +#define soap_write_PointerTons1__ClientLib(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTons1__ClientLib(soap, data), 0) || soap_put_PointerTons1__ClientLib(soap, data, "ns1:ClientLib", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__ClientLib(struct soap*, ns1__ClientLib *const*, const char*, const char*); + +#ifndef soap_read_PointerTons1__ClientLib +#define soap_read_PointerTons1__ClientLib(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTons1__ClientLib(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__ClientLib ** SOAP_FMAC4 soap_get_PointerTons1__ClientLib(struct soap*, ns1__ClientLib **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTo_xop__Include +#define SOAP_TYPE_PointerTo_xop__Include (35) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTo_xop__Include(struct soap*, struct _xop__Include *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTo_xop__Include(struct soap*, const char *, int, struct _xop__Include *const*, const char *); +SOAP_FMAC3 struct _xop__Include ** SOAP_FMAC4 soap_in_PointerTo_xop__Include(struct soap*, const char*, struct _xop__Include **, const char*); + +#ifndef soap_write_PointerTo_xop__Include +#define soap_write_PointerTo_xop__Include(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTo_xop__Include(soap, data), 0) || soap_put_PointerTo_xop__Include(soap, data, "xop:Include", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTo_xop__Include(struct soap*, struct _xop__Include *const*, const char*, const char*); + +#ifndef soap_read_PointerTo_xop__Include +#define soap_read_PointerTo_xop__Include(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTo_xop__Include(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 struct _xop__Include ** SOAP_FMAC4 soap_get_PointerTo_xop__Include(struct soap*, struct _xop__Include **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTons1__Solution +#define SOAP_TYPE_PointerTons1__Solution (34) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTons1__Solution(struct soap*, ns1__Solution *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTons1__Solution(struct soap*, const char *, int, ns1__Solution *const*, const char *); +SOAP_FMAC3 ns1__Solution ** SOAP_FMAC4 soap_in_PointerTons1__Solution(struct soap*, const char*, ns1__Solution **, const char*); + +#ifndef soap_write_PointerTons1__Solution +#define soap_write_PointerTons1__Solution(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTons1__Solution(soap, data), 0) || soap_put_PointerTons1__Solution(soap, data, "ns1:Solution", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__Solution(struct soap*, ns1__Solution *const*, const char*, const char*); + +#ifndef soap_read_PointerTons1__Solution +#define soap_read_PointerTons1__Solution(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTons1__Solution(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 ns1__Solution ** SOAP_FMAC4 soap_get_PointerTons1__Solution(struct soap*, ns1__Solution **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTostd__wstring +#define SOAP_TYPE_PointerTostd__wstring (33) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTostd__wstring(struct soap*, std::wstring *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTostd__wstring(struct soap*, const char *, int, std::wstring *const*, const char *); +SOAP_FMAC3 std::wstring ** SOAP_FMAC4 soap_in_PointerTostd__wstring(struct soap*, const char*, std::wstring **, const char*); + +#ifndef soap_write_PointerTostd__wstring +#define soap_write_PointerTostd__wstring(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTostd__wstring(soap, data), 0) || soap_put_PointerTostd__wstring(soap, data, "string", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTostd__wstring(struct soap*, std::wstring *const*, const char*, const char*); + +#ifndef soap_read_PointerTostd__wstring +#define soap_read_PointerTostd__wstring(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTostd__wstring(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 std::wstring ** SOAP_FMAC4 soap_get_PointerTostd__wstring(struct soap*, std::wstring **, const char*, const char*); + +#ifndef SOAP_TYPE_PointerTounsignedByte +#define SOAP_TYPE_PointerTounsignedByte (11) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTounsignedByte(struct soap*, unsigned char *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_PointerTounsignedByte(struct soap*, const char *, int, unsigned char *const*, const char *); +SOAP_FMAC3 unsigned char ** SOAP_FMAC4 soap_in_PointerTounsignedByte(struct soap*, const char*, unsigned char **, const char*); + +#ifndef soap_write_PointerTounsignedByte +#define soap_write_PointerTounsignedByte(soap, data) ( soap_begin_send(soap) || (soap_serialize_PointerTounsignedByte(soap, data), 0) || soap_put_PointerTounsignedByte(soap, data, "unsignedByte", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTounsignedByte(struct soap*, unsigned char *const*, const char*, const char*); + +#ifndef soap_read_PointerTounsignedByte +#define soap_read_PointerTounsignedByte(soap, data) ( soap_begin_recv(soap) || !soap_get_PointerTounsignedByte(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 unsigned char ** SOAP_FMAC4 soap_get_PointerTounsignedByte(struct soap*, unsigned char **, const char*, const char*); + +#ifndef SOAP_TYPE__QName +#define SOAP_TYPE__QName (5) +#endif + +#define soap_default__QName(soap, a) soap_default_string(soap, a) + + +#define soap_serialize__QName(soap, a) soap_serialize_string(soap, a) + +SOAP_FMAC3 int SOAP_FMAC4 soap_out__QName(struct soap*, const char*, int, char*const*, const char*); +SOAP_FMAC3 char * * SOAP_FMAC4 soap_in__QName(struct soap*, const char*, char **, const char*); + +#ifndef soap_write__QName +#define soap_write__QName(soap, data) ( soap_begin_send(soap) || (soap_serialize__QName(soap, data), 0) || soap_put__QName(soap, data, "byte", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put__QName(struct soap*, char *const*, const char*, const char*); + +#ifndef soap_read__QName +#define soap_read__QName(soap, data) ( soap_begin_recv(soap) || !soap_get__QName(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 char ** SOAP_FMAC4 soap_get__QName(struct soap*, char **, const char*, const char*); + +#ifndef SOAP_TYPE_string +#define SOAP_TYPE_string (4) +#endif +SOAP_FMAC3 void SOAP_FMAC4 soap_default_string(struct soap*, char **); +SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_string(struct soap*, char *const*); +SOAP_FMAC3 int SOAP_FMAC4 soap_out_string(struct soap*, const char*, int, char*const*, const char*); +SOAP_FMAC3 char * * SOAP_FMAC4 soap_in_string(struct soap*, const char*, char **, const char*); + +#ifndef soap_write_string +#define soap_write_string(soap, data) ( soap_begin_send(soap) || (soap_serialize_string(soap, data), 0) || soap_put_string(soap, data, "byte", NULL) || soap_end_send(soap) ) +#endif + +SOAP_FMAC3 int SOAP_FMAC4 soap_put_string(struct soap*, char *const*, const char*, const char*); + +#ifndef soap_read_string +#define soap_read_string(soap, data) ( soap_begin_recv(soap) || !soap_get_string(soap, data, NULL, NULL) || soap_end_recv(soap) ) +#endif + +SOAP_FMAC3 char ** SOAP_FMAC4 soap_get_string(struct soap*, char **, const char*, const char*); + +#endif + +/* End of soapH.h */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapStub.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapStub.h new file mode 100644 index 000000000..992a8a71a --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapStub.h @@ -0,0 +1,546 @@ +/* soapStub.h + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#ifndef soapStub_H +#define soapStub_H +#include +#define SOAP_NAMESPACE_OF_ns1 "https://www.crash-server.com/" +#define SOAP_NAMESPACE_OF_ns2 "http://microsoft.com/wsdl/types/" +#include "stdsoap2.h" + +/******************************************************************************\ + * * + * Enumerations * + * * +\******************************************************************************/ + + +#ifndef SOAP_TYPE_ns1__Architecture +#define SOAP_TYPE_ns1__Architecture (24) +/* ns1:Architecture */ +enum ns1__Architecture {ns1__Architecture__x32 = 0, ns1__Architecture__x64 = 1}; +#endif + +#ifndef SOAP_TYPE_ns1__ResponseType +#define SOAP_TYPE_ns1__ResponseType (25) +/* ns1:ResponseType */ +enum ns1__ResponseType {ns1__ResponseType__HaveSolution = 0, ns1__ResponseType__NeedMiniDump = 1, ns1__ResponseType__NeedMoreInfo = 2, ns1__ResponseType__Stop = 3, ns1__ResponseType__Error = 4}; +#endif + +#ifndef SOAP_TYPE_ns1__SolutionType +#define SOAP_TYPE_ns1__SolutionType (26) +/* ns1:SolutionType */ +enum ns1__SolutionType {ns1__SolutionType__Url = 0, ns1__SolutionType__Exe = 1}; +#endif + +#ifndef SOAP_TYPE_ns1__AdditionalInfoType +#define SOAP_TYPE_ns1__AdditionalInfoType (27) +/* ns1:AdditionalInfoType */ +enum ns1__AdditionalInfoType {ns1__AdditionalInfoType__None = 0, ns1__AdditionalInfoType__FullDump = 1, ns1__AdditionalInfoType__Info = 2}; +#endif + +/******************************************************************************\ + * * + * Types with Custom Serializers * + * * +\******************************************************************************/ + + +/******************************************************************************\ + * * + * Classes and Structs * + * * +\******************************************************************************/ + + +#if 0 /* volatile type: do not declare here, declared elsewhere */ + +#endif + +#ifndef SOAP_TYPE__xop__Include +#define SOAP_TYPE__xop__Include (8) +/* Base64 schema type: */ +struct _xop__Include +{ +public: + unsigned char *__ptr; + int __size; + char *id; /* optional element of type xsd:string */ + char *type; /* optional element of type xsd:string */ + char *options; /* optional element of type xsd:string */ +}; +typedef struct _xop__Include _xop__Include; +#endif + +#if 0 /* volatile type: do not declare here, declared elsewhere */ + +#endif + +#ifndef SOAP_TYPE_ns1__ClientLib +#define SOAP_TYPE_ns1__ClientLib (12) +/* ns1:ClientLib */ +class SOAP_CMAC ns1__ClientLib +{ +public: + unsigned short v1; /* required element of type xsd:unsignedShort */ + unsigned short v2; /* required element of type xsd:unsignedShort */ + unsigned short v3; /* required element of type xsd:unsignedShort */ + unsigned short v4; /* required element of type xsd:unsignedShort */ + enum ns1__Architecture arch; /* required element of type ns1:Architecture */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 12; } /* = unique id SOAP_TYPE_ns1__ClientLib */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + ns1__ClientLib(): soap(NULL) { ns1__ClientLib::soap_default(NULL); } + virtual ~ns1__ClientLib() { } +}; +#endif + +#ifndef SOAP_TYPE_ns1__Application +#define SOAP_TYPE_ns1__Application (13) +/* ns1:Application */ +class SOAP_CMAC ns1__Application +{ +public: + std::wstring applicationGUID; /* required element of type ns2:guid */ + unsigned short v1; /* required element of type xsd:unsignedShort */ + unsigned short v2; /* required element of type xsd:unsignedShort */ + unsigned short v3; /* required element of type xsd:unsignedShort */ + unsigned short v4; /* required element of type xsd:unsignedShort */ + unsigned short hotfix; /* required element of type xsd:unsignedShort */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 13; } /* = unique id SOAP_TYPE_ns1__Application */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + ns1__Application(): soap(NULL) { ns1__Application::soap_default(NULL); } + virtual ~ns1__Application() { } +}; +#endif + +#ifndef SOAP_TYPE_ns1__Response +#define SOAP_TYPE_ns1__Response (14) +/* ns1:Response */ +class SOAP_CMAC ns1__Response +{ +public: + enum ns1__ResponseType type; /* required element of type ns1:ResponseType */ + std::wstring *error; /* optional element of type xsd:string */ + class ns1__Solution *solution; /* optional element of type ns1:Solution */ + std::wstring *clientID; /* optional element of type xsd:string */ + int problemID; /* required element of type xsd:int */ + int dumpGroupID; /* required element of type xsd:int */ + int dumpID; /* required element of type xsd:int */ + std::wstring *urlToProblem; /* optional element of type xsd:string */ + enum ns1__AdditionalInfoType infoType; /* required element of type ns1:AdditionalInfoType */ + struct _xop__Include *infoModule; /* optional element of type xop:Include */ + std::wstring *infoModuleCfg; /* optional element of type xsd:string */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 14; } /* = unique id SOAP_TYPE_ns1__Response */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + ns1__Response(): error(NULL), solution(NULL), clientID(NULL), urlToProblem(NULL), infoModule(NULL), infoModuleCfg(NULL), soap(NULL) { ns1__Response::soap_default(NULL); } + virtual ~ns1__Response() { } +}; +#endif + +#ifndef SOAP_TYPE_ns1__Solution +#define SOAP_TYPE_ns1__Solution (15) +/* ns1:Solution */ +class SOAP_CMAC ns1__Solution +{ +public: + bool askConfirmation; /* required element of type xsd:boolean */ + enum ns1__SolutionType type; /* required element of type ns1:SolutionType */ + std::wstring *url; /* optional element of type xsd:string */ + struct _xop__Include *exe; /* optional element of type xop:Include */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 15; } /* = unique id SOAP_TYPE_ns1__Solution */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + ns1__Solution(): url(NULL), exe(NULL), soap(NULL) { ns1__Solution::soap_default(NULL); } + virtual ~ns1__Solution() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__Hello +#define SOAP_TYPE__ns1__Hello (16) +/* ns1:Hello */ +class SOAP_CMAC _ns1__Hello +{ +public: + ns1__ClientLib *client; /* optional element of type ns1:ClientLib */ + ns1__Application *app; /* optional element of type ns1:Application */ + std::wstring *mainModule; /* optional element of type xsd:string */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 16; } /* = unique id SOAP_TYPE__ns1__Hello */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__Hello(): client(NULL), app(NULL), mainModule(NULL), soap(NULL) { _ns1__Hello::soap_default(NULL); } + virtual ~_ns1__Hello() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__HelloResponse +#define SOAP_TYPE__ns1__HelloResponse (17) +/* ns1:HelloResponse */ +class SOAP_CMAC _ns1__HelloResponse +{ +public: + ns1__Response *HelloResult; /* SOAP 1.2 RPC return element (when namespace qualified) */ /* optional element of type ns1:Response */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 17; } /* = unique id SOAP_TYPE__ns1__HelloResponse */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__HelloResponse(): HelloResult(NULL), soap(NULL) { _ns1__HelloResponse::soap_default(NULL); } + virtual ~_ns1__HelloResponse() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__UploadMiniDump +#define SOAP_TYPE__ns1__UploadMiniDump (18) +/* ns1:UploadMiniDump */ +class SOAP_CMAC _ns1__UploadMiniDump +{ +public: + ns1__ClientLib *client; /* optional element of type ns1:ClientLib */ + ns1__Application *app; /* optional element of type ns1:Application */ + std::wstring *mainModule; /* optional element of type xsd:string */ + int PCID; /* required element of type xsd:int */ + int submitterID; /* required element of type xsd:int */ + struct _xop__Include *dump; /* optional element of type xop:Include */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 18; } /* = unique id SOAP_TYPE__ns1__UploadMiniDump */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__UploadMiniDump(): client(NULL), app(NULL), mainModule(NULL), dump(NULL), soap(NULL) { _ns1__UploadMiniDump::soap_default(NULL); } + virtual ~_ns1__UploadMiniDump() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__UploadMiniDumpResponse +#define SOAP_TYPE__ns1__UploadMiniDumpResponse (19) +/* ns1:UploadMiniDumpResponse */ +class SOAP_CMAC _ns1__UploadMiniDumpResponse +{ +public: + ns1__Response *UploadMiniDumpResult; /* SOAP 1.2 RPC return element (when namespace qualified) */ /* optional element of type ns1:Response */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 19; } /* = unique id SOAP_TYPE__ns1__UploadMiniDumpResponse */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__UploadMiniDumpResponse(): UploadMiniDumpResult(NULL), soap(NULL) { _ns1__UploadMiniDumpResponse::soap_default(NULL); } + virtual ~_ns1__UploadMiniDumpResponse() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__UploadAdditionalInfo +#define SOAP_TYPE__ns1__UploadAdditionalInfo (20) +/* ns1:UploadAdditionalInfo */ +class SOAP_CMAC _ns1__UploadAdditionalInfo +{ +public: + ns1__ClientLib *client; /* optional element of type ns1:ClientLib */ + ns1__Application *app; /* optional element of type ns1:Application */ + std::wstring *mainModule; /* optional element of type xsd:string */ + int miniDumpID; /* required element of type xsd:int */ + struct _xop__Include *info; /* optional element of type xop:Include */ + enum ns1__AdditionalInfoType infoType; /* required element of type ns1:AdditionalInfoType */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 20; } /* = unique id SOAP_TYPE__ns1__UploadAdditionalInfo */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__UploadAdditionalInfo(): client(NULL), app(NULL), mainModule(NULL), info(NULL), soap(NULL) { _ns1__UploadAdditionalInfo::soap_default(NULL); } + virtual ~_ns1__UploadAdditionalInfo() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__UploadAdditionalInfoResponse +#define SOAP_TYPE__ns1__UploadAdditionalInfoResponse (21) +/* ns1:UploadAdditionalInfoResponse */ +class SOAP_CMAC _ns1__UploadAdditionalInfoResponse +{ +public: + ns1__Response *UploadAdditionalInfoResult; /* SOAP 1.2 RPC return element (when namespace qualified) */ /* optional element of type ns1:Response */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 21; } /* = unique id SOAP_TYPE__ns1__UploadAdditionalInfoResponse */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__UploadAdditionalInfoResponse(): UploadAdditionalInfoResult(NULL), soap(NULL) { _ns1__UploadAdditionalInfoResponse::soap_default(NULL); } + virtual ~_ns1__UploadAdditionalInfoResponse() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__UploadSymbol +#define SOAP_TYPE__ns1__UploadSymbol (22) +/* ns1:UploadSymbol */ +class SOAP_CMAC _ns1__UploadSymbol +{ +public: + ns1__ClientLib *client; /* optional element of type ns1:ClientLib */ + ns1__Application *app; /* optional element of type ns1:Application */ + bool publish; /* required element of type xsd:boolean */ + struct _xop__Include *sym; /* optional element of type xop:Include */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 22; } /* = unique id SOAP_TYPE__ns1__UploadSymbol */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__UploadSymbol(): client(NULL), app(NULL), sym(NULL), soap(NULL) { _ns1__UploadSymbol::soap_default(NULL); } + virtual ~_ns1__UploadSymbol() { } +}; +#endif + +#ifndef SOAP_TYPE__ns1__UploadSymbolResponse +#define SOAP_TYPE__ns1__UploadSymbolResponse (23) +/* ns1:UploadSymbolResponse */ +class SOAP_CMAC _ns1__UploadSymbolResponse +{ +public: + std::wstring *UploadSymbolResult; /* SOAP 1.2 RPC return element (when namespace qualified) */ /* optional element of type xsd:string */ + struct soap *soap; /* transient */ +public: + virtual int soap_type() const { return 23; } /* = unique id SOAP_TYPE__ns1__UploadSymbolResponse */ + virtual void soap_default(struct soap*); + virtual void soap_serialize(struct soap*) const; + virtual int soap_put(struct soap*, const char*, const char*) const; + virtual int soap_out(struct soap*, const char*, int, const char*) const; + virtual void *soap_get(struct soap*, const char*, const char*); + virtual void *soap_in(struct soap*, const char*, const char*); + _ns1__UploadSymbolResponse(): UploadSymbolResult(NULL), soap(NULL) { _ns1__UploadSymbolResponse::soap_default(NULL); } + virtual ~_ns1__UploadSymbolResponse() { } +}; +#endif + +#ifndef SOAP_TYPE___ns3__Hello +#define SOAP_TYPE___ns3__Hello (43) +/* Operation wrapper: */ +struct __ns3__Hello +{ +public: + _ns1__Hello *ns1__Hello; /* optional element of type ns1:Hello */ +}; +#endif + +#ifndef SOAP_TYPE___ns3__UploadMiniDump +#define SOAP_TYPE___ns3__UploadMiniDump (47) +/* Operation wrapper: */ +struct __ns3__UploadMiniDump +{ +public: + _ns1__UploadMiniDump *ns1__UploadMiniDump; /* optional element of type ns1:UploadMiniDump */ +}; +#endif + +#ifndef SOAP_TYPE___ns3__UploadAdditionalInfo +#define SOAP_TYPE___ns3__UploadAdditionalInfo (51) +/* Operation wrapper: */ +struct __ns3__UploadAdditionalInfo +{ +public: + _ns1__UploadAdditionalInfo *ns1__UploadAdditionalInfo; /* optional element of type ns1:UploadAdditionalInfo */ +}; +#endif + +#ifndef SOAP_TYPE___ns3__UploadSymbol +#define SOAP_TYPE___ns3__UploadSymbol (55) +/* Operation wrapper: */ +struct __ns3__UploadSymbol +{ +public: + _ns1__UploadSymbol *ns1__UploadSymbol; /* optional element of type ns1:UploadSymbol */ +}; +#endif + +#ifndef SOAP_TYPE___ns4__Hello +#define SOAP_TYPE___ns4__Hello (57) +/* Operation wrapper: */ +struct __ns4__Hello +{ +public: + _ns1__Hello *ns1__Hello; /* optional element of type ns1:Hello */ +}; +#endif + +#ifndef SOAP_TYPE___ns4__UploadMiniDump +#define SOAP_TYPE___ns4__UploadMiniDump (59) +/* Operation wrapper: */ +struct __ns4__UploadMiniDump +{ +public: + _ns1__UploadMiniDump *ns1__UploadMiniDump; /* optional element of type ns1:UploadMiniDump */ +}; +#endif + +#ifndef SOAP_TYPE___ns4__UploadAdditionalInfo +#define SOAP_TYPE___ns4__UploadAdditionalInfo (61) +/* Operation wrapper: */ +struct __ns4__UploadAdditionalInfo +{ +public: + _ns1__UploadAdditionalInfo *ns1__UploadAdditionalInfo; /* optional element of type ns1:UploadAdditionalInfo */ +}; +#endif + +#ifndef SOAP_TYPE___ns4__UploadSymbol +#define SOAP_TYPE___ns4__UploadSymbol (63) +/* Operation wrapper: */ +struct __ns4__UploadSymbol +{ +public: + _ns1__UploadSymbol *ns1__UploadSymbol; /* optional element of type ns1:UploadSymbol */ +}; +#endif + +#ifndef SOAP_TYPE_SOAP_ENV__Header +#define SOAP_TYPE_SOAP_ENV__Header (64) +/* SOAP Header: */ +struct SOAP_ENV__Header +{ +#ifdef WITH_NOEMPTYSTRUCT +private: + char dummy; /* dummy member to enable compilation */ +#endif +}; +#endif + +#ifndef SOAP_TYPE_SOAP_ENV__Code +#define SOAP_TYPE_SOAP_ENV__Code (65) +/* SOAP Fault Code: */ +struct SOAP_ENV__Code +{ +public: + char *SOAP_ENV__Value; /* optional element of type xsd:QName */ + struct SOAP_ENV__Code *SOAP_ENV__Subcode; /* optional element of type SOAP-ENV:Code */ +}; +#endif + +#ifndef SOAP_TYPE_SOAP_ENV__Detail +#define SOAP_TYPE_SOAP_ENV__Detail (67) +/* SOAP-ENV:Detail */ +struct SOAP_ENV__Detail +{ +public: + int __type; /* any type of element (defined below) */ + void *fault; /* transient */ + char *__any; +}; +#endif + +#ifndef SOAP_TYPE_SOAP_ENV__Reason +#define SOAP_TYPE_SOAP_ENV__Reason (70) +/* SOAP-ENV:Reason */ +struct SOAP_ENV__Reason +{ +public: + char *SOAP_ENV__Text; /* optional element of type xsd:string */ +}; +#endif + +#ifndef SOAP_TYPE_SOAP_ENV__Fault +#define SOAP_TYPE_SOAP_ENV__Fault (71) +/* SOAP Fault: */ +struct SOAP_ENV__Fault +{ +public: + char *faultcode; /* optional element of type xsd:QName */ + char *faultstring; /* optional element of type xsd:string */ + char *faultactor; /* optional element of type xsd:string */ + struct SOAP_ENV__Detail *detail; /* optional element of type SOAP-ENV:Detail */ + struct SOAP_ENV__Code *SOAP_ENV__Code; /* optional element of type SOAP-ENV:Code */ + struct SOAP_ENV__Reason *SOAP_ENV__Reason; /* optional element of type SOAP-ENV:Reason */ + char *SOAP_ENV__Node; /* optional element of type xsd:string */ + char *SOAP_ENV__Role; /* optional element of type xsd:string */ + struct SOAP_ENV__Detail *SOAP_ENV__Detail; /* optional element of type SOAP-ENV:Detail */ +}; +#endif + +/******************************************************************************\ + * * + * Typedefs * + * * +\******************************************************************************/ + +#ifndef SOAP_TYPE__QName +#define SOAP_TYPE__QName (5) +typedef char *_QName; +#endif + +#ifndef SOAP_TYPE__XML +#define SOAP_TYPE__XML (6) +typedef char *_XML; +#endif + +#ifndef SOAP_TYPE_ns2__guid +#define SOAP_TYPE_ns2__guid (29) +typedef std::wstring ns2__guid; +#endif + + +/******************************************************************************\ + * * + * Externals * + * * +\******************************************************************************/ + + +#endif + +/* End of soapStub.h */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.cpp b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.cpp new file mode 100644 index 000000000..b4b8dfc45 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.cpp @@ -0,0 +1,294 @@ +/* soapUploaderSoap12Proxy.cpp + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#include "soapUploaderSoap12Proxy.h" + +UploaderSoap12Proxy::UploaderSoap12Proxy() +{ UploaderSoap12Proxy_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT); +} + +UploaderSoap12Proxy::UploaderSoap12Proxy(const struct soap &_soap) : soap(_soap) +{ } + +UploaderSoap12Proxy::UploaderSoap12Proxy(soap_mode iomode) +{ UploaderSoap12Proxy_init(iomode, iomode); +} + +UploaderSoap12Proxy::UploaderSoap12Proxy(soap_mode imode, soap_mode omode) +{ UploaderSoap12Proxy_init(imode, omode); +} + +void UploaderSoap12Proxy::UploaderSoap12Proxy_init(soap_mode imode, soap_mode omode) +{ soap_imode(this, imode); + soap_omode(this, omode); + soap_endpoint = NULL; + static const struct Namespace namespaces[] = +{ + {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://www.w3.org/2003/05/soap-envelope", NULL}, + {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://www.w3.org/2003/05/soap-encoding", NULL}, + {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, + {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, + {"xop", "http://www.w3.org/2004/08/xop/include", NULL, NULL}, + {"ns2", "http://microsoft.com/wsdl/types/", NULL, NULL}, + {"ns3", "https://www.crash-server.com/UploaderSoap", NULL, NULL}, + {"ns1", "https://www.crash-server.com/", NULL, NULL}, + {"ns4", "https://www.crash-server.com/UploaderSoap12", NULL, NULL}, + {NULL, NULL, NULL, NULL} +}; + this->namespaces = namespaces; +} + +UploaderSoap12Proxy::~UploaderSoap12Proxy() +{ } + +void UploaderSoap12Proxy::destroy() +{ soap_destroy(this); + soap_end(this); +} + +void UploaderSoap12Proxy::soap_noheader() +{ header = NULL; +} + +const SOAP_ENV__Fault *UploaderSoap12Proxy::soap_fault() +{ return this->fault; +} + +const char *UploaderSoap12Proxy::soap_fault_string() +{ return *soap_faultstring(this); +} + +const char *UploaderSoap12Proxy::soap_fault_detail() +{ return *soap_faultdetail(this); +} + +int UploaderSoap12Proxy::soap_close_socket() +{ return soap_closesock(this); +} + +void UploaderSoap12Proxy::soap_print_fault(FILE *fd) +{ ::soap_print_fault(this, fd); +} + +#ifndef WITH_LEAN +void UploaderSoap12Proxy::soap_stream_fault(std::ostream& os) +{ ::soap_stream_fault(this, os); +} + +char *UploaderSoap12Proxy::soap_sprint_fault(char *buf, size_t len) +{ return ::soap_sprint_fault(this, buf, len); +} +#endif + +int UploaderSoap12Proxy::Hello(_ns1__Hello *ns1__Hello, _ns1__HelloResponse *ns1__HelloResponse) +{ struct soap *soap = this; + struct __ns4__Hello soap_tmp___ns4__Hello; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/Hello"; + soap->encodingStyle = NULL; + soap_tmp___ns4__Hello.ns1__Hello = ns1__Hello; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns4__Hello(soap, &soap_tmp___ns4__Hello); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__Hello(soap, &soap_tmp___ns4__Hello, "-ns4:Hello", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__Hello(soap, &soap_tmp___ns4__Hello, "-ns4:Hello", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__HelloResponse) + return soap_closesock(soap); + ns1__HelloResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__HelloResponse->soap_get(soap, "ns1:HelloResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} + +int UploaderSoap12Proxy::UploadMiniDump(_ns1__UploadMiniDump *ns1__UploadMiniDump, _ns1__UploadMiniDumpResponse *ns1__UploadMiniDumpResponse) +{ struct soap *soap = this; + struct __ns4__UploadMiniDump soap_tmp___ns4__UploadMiniDump; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/UploadMiniDump"; + soap->encodingStyle = NULL; + soap_tmp___ns4__UploadMiniDump.ns1__UploadMiniDump = ns1__UploadMiniDump; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns4__UploadMiniDump(soap, &soap_tmp___ns4__UploadMiniDump); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__UploadMiniDump(soap, &soap_tmp___ns4__UploadMiniDump, "-ns4:UploadMiniDump", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__UploadMiniDump(soap, &soap_tmp___ns4__UploadMiniDump, "-ns4:UploadMiniDump", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__UploadMiniDumpResponse) + return soap_closesock(soap); + ns1__UploadMiniDumpResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__UploadMiniDumpResponse->soap_get(soap, "ns1:UploadMiniDumpResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} + +int UploaderSoap12Proxy::UploadAdditionalInfo(_ns1__UploadAdditionalInfo *ns1__UploadAdditionalInfo, _ns1__UploadAdditionalInfoResponse *ns1__UploadAdditionalInfoResponse) +{ struct soap *soap = this; + struct __ns4__UploadAdditionalInfo soap_tmp___ns4__UploadAdditionalInfo; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/UploadAdditionalInfo"; + soap->encodingStyle = NULL; + soap_tmp___ns4__UploadAdditionalInfo.ns1__UploadAdditionalInfo = ns1__UploadAdditionalInfo; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns4__UploadAdditionalInfo(soap, &soap_tmp___ns4__UploadAdditionalInfo); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__UploadAdditionalInfo(soap, &soap_tmp___ns4__UploadAdditionalInfo, "-ns4:UploadAdditionalInfo", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__UploadAdditionalInfo(soap, &soap_tmp___ns4__UploadAdditionalInfo, "-ns4:UploadAdditionalInfo", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__UploadAdditionalInfoResponse) + return soap_closesock(soap); + ns1__UploadAdditionalInfoResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__UploadAdditionalInfoResponse->soap_get(soap, "ns1:UploadAdditionalInfoResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} + +int UploaderSoap12Proxy::UploadSymbol(_ns1__UploadSymbol *ns1__UploadSymbol, _ns1__UploadSymbolResponse *ns1__UploadSymbolResponse) +{ struct soap *soap = this; + struct __ns4__UploadSymbol soap_tmp___ns4__UploadSymbol; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/UploadSymbol"; + soap->encodingStyle = NULL; + soap_tmp___ns4__UploadSymbol.ns1__UploadSymbol = ns1__UploadSymbol; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns4__UploadSymbol(soap, &soap_tmp___ns4__UploadSymbol); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__UploadSymbol(soap, &soap_tmp___ns4__UploadSymbol, "-ns4:UploadSymbol", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns4__UploadSymbol(soap, &soap_tmp___ns4__UploadSymbol, "-ns4:UploadSymbol", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__UploadSymbolResponse) + return soap_closesock(soap); + ns1__UploadSymbolResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__UploadSymbolResponse->soap_get(soap, "ns1:UploadSymbolResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} +/* End of client proxy code */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.h new file mode 100644 index 000000000..29a71f13a --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoap12Proxy.h @@ -0,0 +1,61 @@ +/* soapUploaderSoap12Proxy.h + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#ifndef soapUploaderSoap12Proxy_H +#define soapUploaderSoap12Proxy_H +#include "soapH.h" + +class SOAP_CMAC UploaderSoap12Proxy : public soap +{ public: + /// Endpoint URL of service 'UploaderSoap12Proxy' (change as needed) + const char *soap_endpoint; + /// Constructor + UploaderSoap12Proxy(); + /// Constructor with copy of another engine state + UploaderSoap12Proxy(const struct soap&); + /// Constructor with engine input+output mode control + UploaderSoap12Proxy(soap_mode iomode); + /// Constructor with engine input and output mode control + UploaderSoap12Proxy(soap_mode imode, soap_mode omode); + /// Destructor frees deserialized data + virtual ~UploaderSoap12Proxy(); + /// Initializer used by constructors + virtual void UploaderSoap12Proxy_init(soap_mode imode, soap_mode omode); + /// Delete all deserialized data (uses soap_destroy and soap_end) + virtual void destroy(); + /// Disables and removes SOAP Header from message + virtual void soap_noheader(); + /// Get SOAP Fault structure (NULL when absent) + virtual const SOAP_ENV__Fault *soap_fault(); + /// Get SOAP Fault string (NULL when absent) + virtual const char *soap_fault_string(); + /// Get SOAP Fault detail as string (NULL when absent) + virtual const char *soap_fault_detail(); + /// Force close connection (normally automatic, except for send_X ops) + virtual int soap_close_socket(); + /// Print fault + virtual void soap_print_fault(FILE*); +#ifndef WITH_LEAN + /// Print fault to stream + virtual void soap_stream_fault(std::ostream&); + /// Put fault into buffer + virtual char *soap_sprint_fault(char *buf, size_t len); +#endif + + /// Web service operation 'Hello' (returns error code or SOAP_OK) + virtual int Hello(_ns1__Hello *ns1__Hello, _ns1__HelloResponse *ns1__HelloResponse); + + /// Web service operation 'UploadMiniDump' (returns error code or SOAP_OK) + virtual int UploadMiniDump(_ns1__UploadMiniDump *ns1__UploadMiniDump, _ns1__UploadMiniDumpResponse *ns1__UploadMiniDumpResponse); + + /// Web service operation 'UploadAdditionalInfo' (returns error code or SOAP_OK) + virtual int UploadAdditionalInfo(_ns1__UploadAdditionalInfo *ns1__UploadAdditionalInfo, _ns1__UploadAdditionalInfoResponse *ns1__UploadAdditionalInfoResponse); + + /// Web service operation 'UploadSymbol' (returns error code or SOAP_OK) + virtual int UploadSymbol(_ns1__UploadSymbol *ns1__UploadSymbol, _ns1__UploadSymbolResponse *ns1__UploadSymbolResponse); +}; +#endif diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.cpp b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.cpp new file mode 100644 index 000000000..a7cabaf91 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.cpp @@ -0,0 +1,294 @@ +/* soapUploaderSoapProxy.cpp + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#include "soapUploaderSoapProxy.h" + +UploaderSoapProxy::UploaderSoapProxy() +{ UploaderSoapProxy_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT); +} + +UploaderSoapProxy::UploaderSoapProxy(const struct soap &_soap) : soap(_soap) +{ } + +UploaderSoapProxy::UploaderSoapProxy(soap_mode iomode) +{ UploaderSoapProxy_init(iomode, iomode); +} + +UploaderSoapProxy::UploaderSoapProxy(soap_mode imode, soap_mode omode) +{ UploaderSoapProxy_init(imode, omode); +} + +void UploaderSoapProxy::UploaderSoapProxy_init(soap_mode imode, soap_mode omode) +{ soap_imode(this, imode); + soap_omode(this, omode); + soap_endpoint = NULL; + static const struct Namespace namespaces[] = +{ + {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://www.w3.org/2003/05/soap-envelope", NULL}, + {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://www.w3.org/2003/05/soap-encoding", NULL}, + {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, + {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, + {"xop", "http://www.w3.org/2004/08/xop/include", NULL, NULL}, + {"ns2", "http://microsoft.com/wsdl/types/", NULL, NULL}, + {"ns3", "https://www.crash-server.com/UploaderSoap", NULL, NULL}, + {"ns1", "https://www.crash-server.com/", NULL, NULL}, + {"ns4", "https://www.crash-server.com/UploaderSoap12", NULL, NULL}, + {NULL, NULL, NULL, NULL} +}; + this->namespaces = namespaces; +} + +UploaderSoapProxy::~UploaderSoapProxy() +{ } + +void UploaderSoapProxy::destroy() +{ soap_destroy(this); + soap_end(this); +} + +void UploaderSoapProxy::soap_noheader() +{ header = NULL; +} + +const SOAP_ENV__Fault *UploaderSoapProxy::soap_fault() +{ return this->fault; +} + +const char *UploaderSoapProxy::soap_fault_string() +{ return *soap_faultstring(this); +} + +const char *UploaderSoapProxy::soap_fault_detail() +{ return *soap_faultdetail(this); +} + +int UploaderSoapProxy::soap_close_socket() +{ return soap_closesock(this); +} + +void UploaderSoapProxy::soap_print_fault(FILE *fd) +{ ::soap_print_fault(this, fd); +} + +#ifndef WITH_LEAN +void UploaderSoapProxy::soap_stream_fault(std::ostream& os) +{ ::soap_stream_fault(this, os); +} + +char *UploaderSoapProxy::soap_sprint_fault(char *buf, size_t len) +{ return ::soap_sprint_fault(this, buf, len); +} +#endif + +int UploaderSoapProxy::Hello(_ns1__Hello *ns1__Hello, _ns1__HelloResponse *ns1__HelloResponse) +{ struct soap *soap = this; + struct __ns3__Hello soap_tmp___ns3__Hello; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/Hello"; + soap->encodingStyle = NULL; + soap_tmp___ns3__Hello.ns1__Hello = ns1__Hello; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns3__Hello(soap, &soap_tmp___ns3__Hello); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__Hello(soap, &soap_tmp___ns3__Hello, "-ns3:Hello", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__Hello(soap, &soap_tmp___ns3__Hello, "-ns3:Hello", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__HelloResponse) + return soap_closesock(soap); + ns1__HelloResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__HelloResponse->soap_get(soap, "ns1:HelloResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} + +int UploaderSoapProxy::UploadMiniDump(_ns1__UploadMiniDump *ns1__UploadMiniDump, _ns1__UploadMiniDumpResponse *ns1__UploadMiniDumpResponse) +{ struct soap *soap = this; + struct __ns3__UploadMiniDump soap_tmp___ns3__UploadMiniDump; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/UploadMiniDump"; + soap->encodingStyle = NULL; + soap_tmp___ns3__UploadMiniDump.ns1__UploadMiniDump = ns1__UploadMiniDump; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns3__UploadMiniDump(soap, &soap_tmp___ns3__UploadMiniDump); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__UploadMiniDump(soap, &soap_tmp___ns3__UploadMiniDump, "-ns3:UploadMiniDump", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__UploadMiniDump(soap, &soap_tmp___ns3__UploadMiniDump, "-ns3:UploadMiniDump", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__UploadMiniDumpResponse) + return soap_closesock(soap); + ns1__UploadMiniDumpResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__UploadMiniDumpResponse->soap_get(soap, "ns1:UploadMiniDumpResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} + +int UploaderSoapProxy::UploadAdditionalInfo(_ns1__UploadAdditionalInfo *ns1__UploadAdditionalInfo, _ns1__UploadAdditionalInfoResponse *ns1__UploadAdditionalInfoResponse) +{ struct soap *soap = this; + struct __ns3__UploadAdditionalInfo soap_tmp___ns3__UploadAdditionalInfo; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/UploadAdditionalInfo"; + soap->encodingStyle = NULL; + soap_tmp___ns3__UploadAdditionalInfo.ns1__UploadAdditionalInfo = ns1__UploadAdditionalInfo; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns3__UploadAdditionalInfo(soap, &soap_tmp___ns3__UploadAdditionalInfo); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__UploadAdditionalInfo(soap, &soap_tmp___ns3__UploadAdditionalInfo, "-ns3:UploadAdditionalInfo", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__UploadAdditionalInfo(soap, &soap_tmp___ns3__UploadAdditionalInfo, "-ns3:UploadAdditionalInfo", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__UploadAdditionalInfoResponse) + return soap_closesock(soap); + ns1__UploadAdditionalInfoResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__UploadAdditionalInfoResponse->soap_get(soap, "ns1:UploadAdditionalInfoResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} + +int UploaderSoapProxy::UploadSymbol(_ns1__UploadSymbol *ns1__UploadSymbol, _ns1__UploadSymbolResponse *ns1__UploadSymbolResponse) +{ struct soap *soap = this; + struct __ns3__UploadSymbol soap_tmp___ns3__UploadSymbol; + const char *soap_action = NULL; + if (!soap_endpoint) + soap_endpoint = "http://localhost:59175/DumpUploader.asmx"; + soap_action = "https://www.crash-server.com/UploadSymbol"; + soap->encodingStyle = NULL; + soap_tmp___ns3__UploadSymbol.ns1__UploadSymbol = ns1__UploadSymbol; + soap_begin(soap); + soap_serializeheader(soap); + soap_serialize___ns3__UploadSymbol(soap, &soap_tmp___ns3__UploadSymbol); + if (soap_begin_count(soap)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__UploadSymbol(soap, &soap_tmp___ns3__UploadSymbol, "-ns3:UploadSymbol", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap->error; + } + if (soap_end_count(soap)) + return soap->error; + if (soap_connect(soap, soap_endpoint, soap_action) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_put___ns3__UploadSymbol(soap, &soap_tmp___ns3__UploadSymbol, "-ns3:UploadSymbol", NULL) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap) + || soap_end_send(soap)) + return soap_closesock(soap); + if (!ns1__UploadSymbolResponse) + return soap_closesock(soap); + ns1__UploadSymbolResponse->soap_default(soap); + if (soap_begin_recv(soap) + || soap_envelope_begin_in(soap) + || soap_recv_header(soap) + || soap_body_begin_in(soap)) + return soap_closesock(soap); + ns1__UploadSymbolResponse->soap_get(soap, "ns1:UploadSymbolResponse", ""); + if (soap->error) + return soap_recv_fault(soap, 0); + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + return soap_closesock(soap); +} +/* End of client proxy code */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.h new file mode 100644 index 000000000..9343019dd --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/generated/soapUploaderSoapProxy.h @@ -0,0 +1,61 @@ +/* soapUploaderSoapProxy.h + Generated by gSOAP 2.8.0 from DumpUploader.h + Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. + The generated code is released under one of the following licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. +*/ + +#ifndef soapUploaderSoapProxy_H +#define soapUploaderSoapProxy_H +#include "soapH.h" + +class SOAP_CMAC UploaderSoapProxy : public soap +{ public: + /// Endpoint URL of service 'UploaderSoapProxy' (change as needed) + const char *soap_endpoint; + /// Constructor + UploaderSoapProxy(); + /// Constructor with copy of another engine state + UploaderSoapProxy(const struct soap&); + /// Constructor with engine input+output mode control + UploaderSoapProxy(soap_mode iomode); + /// Constructor with engine input and output mode control + UploaderSoapProxy(soap_mode imode, soap_mode omode); + /// Destructor frees deserialized data + virtual ~UploaderSoapProxy(); + /// Initializer used by constructors + virtual void UploaderSoapProxy_init(soap_mode imode, soap_mode omode); + /// Delete all deserialized data (uses soap_destroy and soap_end) + virtual void destroy(); + /// Disables and removes SOAP Header from message + virtual void soap_noheader(); + /// Get SOAP Fault structure (NULL when absent) + virtual const SOAP_ENV__Fault *soap_fault(); + /// Get SOAP Fault string (NULL when absent) + virtual const char *soap_fault_string(); + /// Get SOAP Fault detail as string (NULL when absent) + virtual const char *soap_fault_detail(); + /// Force close connection (normally automatic, except for send_X ops) + virtual int soap_close_socket(); + /// Print fault + virtual void soap_print_fault(FILE*); +#ifndef WITH_LEAN + /// Print fault to stream + virtual void soap_stream_fault(std::ostream&); + /// Put fault into buffer + virtual char *soap_sprint_fault(char *buf, size_t len); +#endif + + /// Web service operation 'Hello' (returns error code or SOAP_OK) + virtual int Hello(_ns1__Hello *ns1__Hello, _ns1__HelloResponse *ns1__HelloResponse); + + /// Web service operation 'UploadMiniDump' (returns error code or SOAP_OK) + virtual int UploadMiniDump(_ns1__UploadMiniDump *ns1__UploadMiniDump, _ns1__UploadMiniDumpResponse *ns1__UploadMiniDumpResponse); + + /// Web service operation 'UploadAdditionalInfo' (returns error code or SOAP_OK) + virtual int UploadAdditionalInfo(_ns1__UploadAdditionalInfo *ns1__UploadAdditionalInfo, _ns1__UploadAdditionalInfoResponse *ns1__UploadAdditionalInfoResponse); + + /// Web service operation 'UploadSymbol' (returns error code or SOAP_OK) + virtual int UploadSymbol(_ns1__UploadSymbol *ns1__UploadSymbol, _ns1__UploadSymbolResponse *ns1__UploadSymbolResponse); +}; +#endif diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet-2.8.0.cpp b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet-2.8.0.cpp new file mode 100644 index 000000000..b47d6def3 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet-2.8.0.cpp @@ -0,0 +1,1185 @@ +/* +See the header file for details. This file is distributed under the MIT licence. +*/ + +/* system */ +#include +#include +#include + +/* gsoap */ +#include + +/* local */ +#include "gsoapWinInet.h" + +/* ensure that the wininet library is linked */ +#pragma comment( lib, "wininet.lib" ) +/* disable deprecation warnings */ +#pragma warning(disable : 4996) + +#define UNUSED_ARG(x) (x) +#define INVALID_BUFFER_LENGTH ((DWORD)-1) + +/* plugin id */ +static const char wininet_id[] = "wininet-2.0"; + +/* plugin private data */ +struct wininet_data +{ + HINTERNET hInternet; /* internet session handle */ + HINTERNET hConnection; /* current connection handle */ + BOOL bDisconnect; /* connection is disconnected */ + DWORD dwRequestFlags; /* extra request flags from user */ + char * pBuffer; /* send buffer */ + size_t uiBufferLenMax; /* total length of the message */ + size_t uiBufferLen; /* length of data in buffer */ + BOOL bIsChunkSize; /* expecting a chunk size buffer */ + wininet_rse_callback pRseCallback; /* wininet_resolve_send_error callback. Allows clients to resolve ssl errors programatically */ +#ifdef SOAP_DEBUG + /* this is only used for DBGLOG output */ + char * pszErrorMessage; /* wininet/system error message */ +#endif +}; + +/* forward declarations */ +static BOOL +wininet_init( + struct soap * soap, + struct wininet_data * a_pData, + DWORD a_dwRequestFlags ); +static int +wininet_copy( + struct soap * soap, + struct soap_plugin * a_pDst, + struct soap_plugin * a_pSrc ); +static void +wininet_delete( + struct soap * soap, + struct soap_plugin * a_pPluginData ); +static SOAP_SOCKET +wininet_connect( + struct soap * soap, + const char * a_pszEndpoint, + const char * a_pszHost, + int a_nPort ); +static int +wininet_post_header( + struct soap * soap, + const char * a_pszKey, + const char * a_pszValue ); +static int +wininet_fsend( + struct soap * soap, + const char * a_pBuffer, + size_t a_uiBufferLen ); +static size_t +wininet_frecv( + struct soap * soap, + char * a_pBuffer, + size_t a_uiBufferLen ); +static int +wininet_disconnect( + struct soap * soap ); +void CALLBACK +wininet_callback( + HINTERNET hInternet, + DWORD_PTR dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength ); +static BOOL +wininet_have_connection( + struct soap * soap, + struct wininet_data * a_pData ); +static DWORD +wininet_set_timeout( + struct soap * soap, + struct wininet_data * a_pData, + const char * a_pszTimeout, + DWORD a_dwOption, + int a_nTimeout ); +static BOOL +wininet_resolve_send_error( + HINTERNET a_hHttpRequest, + DWORD a_dwErrorCode ); + +#ifdef SOAP_DEBUG +/* this is only used for DBGLOG output */ +static const char * +wininet_error_message( + struct soap * a_pData, + DWORD a_dwErrorMsgId ); +static void +wininet_free_error_message( + struct wininet_data * a_pData ); +#else +#define wininet_free_error_message(x) +#endif + +/* plugin registration */ +int +wininet_plugin( + struct soap * soap, + struct soap_plugin * a_pPluginData, + void * a_dwRequestFlags ) +{ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: plugin registration\n", soap )); + + a_pPluginData->id = wininet_id; + a_pPluginData->fcopy = wininet_copy; + a_pPluginData->fdelete = wininet_delete; + a_pPluginData->data = (void*) malloc( sizeof(struct wininet_data) ); + if ( !a_pPluginData->data ) + { + return SOAP_EOM; + } + if ( !wininet_init( soap, + (struct wininet_data *) a_pPluginData->data, + (DWORD) (size_t) a_dwRequestFlags ) ) + { + free( a_pPluginData->data ); + return SOAP_EOM; + } + +#ifdef SOAP_DEBUG + if ( (soap->omode & SOAP_IO) == SOAP_IO_STORE ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: use of SOAP_IO_STORE is not recommended\n", soap )); + } +#endif + + return SOAP_OK; +} + +/* initialize private data */ +static BOOL +wininet_init( + struct soap * soap, + struct wininet_data * a_pData, + DWORD a_dwRequestFlags ) +{ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: init private data\n", soap )); + + memset( a_pData, 0, sizeof(struct wininet_data) ); + a_pData->dwRequestFlags = a_dwRequestFlags; + + /* start our internet session */ + a_pData->hInternet = InternetOpenA( + "gSOAP", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); + if ( !a_pData->hInternet ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: init, error %d (%s) in InternetOpen\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + wininet_free_error_message( a_pData ); + return FALSE; + } + + /* set the timeouts, if any of these fail the error isn't fatal */ + wininet_set_timeout( soap, a_pData, "connect", + INTERNET_OPTION_CONNECT_TIMEOUT, soap->connect_timeout ); + wininet_set_timeout( soap, a_pData, "receive", + INTERNET_OPTION_RECEIVE_TIMEOUT, soap->recv_timeout ); + wininet_set_timeout( soap, a_pData, "send", + INTERNET_OPTION_SEND_TIMEOUT, soap->send_timeout ); + + /* set up the callback function so we get notifications */ + InternetSetStatusCallback( a_pData->hInternet, wininet_callback ); + + /* set all of our callbacks */ + soap->fopen = wininet_connect; + soap->fposthdr = wininet_post_header; + soap->fsend = wininet_fsend; + soap->frecv = wininet_frecv; + soap->fclose = wininet_disconnect; + + return TRUE; +} + +void +wininet_set_rse_callback( + struct soap * soap, + wininet_rse_callback a_pRsecallback) +{ + struct wininet_data * pData = (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: resolve_send_error callback = '%p'\n", soap, a_pRsecallback )); + + pData->pRseCallback = a_pRsecallback; +} + + +/* copy the private data structure */ +static int +wininet_copy( + struct soap * soap, + struct soap_plugin * a_pDst, + struct soap_plugin * a_pSrc ) +{ + UNUSED_ARG( soap ); + UNUSED_ARG( a_pDst ); + UNUSED_ARG( a_pSrc ); + + _ASSERTE( !"wininet doesn't support copy" ); + return SOAP_FATAL_ERROR; +} + +/* deallocate of our private structure */ +static void +wininet_delete( + struct soap * soap, + struct soap_plugin * a_pPluginData ) +{ + struct wininet_data * pData = + (struct wininet_data *) a_pPluginData->data; + + UNUSED_ARG( soap ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: delete private data\n", soap )); + + /* force a disconnect of any existing connection */ + pData->bDisconnect = TRUE; + wininet_have_connection( soap, pData ); + + /* close down the internet */ + if ( pData->hInternet ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: closing internet handle\n", soap)); + InternetCloseHandle( pData->hInternet ); + pData->hInternet = NULL; + } + + /* free our data */ + wininet_free_error_message( pData ); + free( a_pPluginData->data ); +} + +/* gsoap documentation: + Called from a client proxy to open a connection to a Web Service located + at endpoint. Input parameters host and port are micro-parsed from endpoint. + Should return a valid file descriptor, or SOAP_INVALID_SOCKET and + soap->error set to an error code. Built-in gSOAP function: tcp_connect +*/ +static SOAP_SOCKET +wininet_connect( + struct soap * soap, + const char * a_pszEndpoint, + const char * a_pszHost, + int a_nPort ) +{ + URL_COMPONENTSA urlComponents; + char szUrlPath[MAX_PATH]; + char szHost[MAX_PATH]; + DWORD dwFlags; + HINTERNET hConnection = NULL; + HINTERNET hHttpRequest = NULL; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + /* we parse the URL ourselves so we don't use these parameters */ + UNUSED_ARG( a_pszHost ); + UNUSED_ARG( a_nPort ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, endpoint = '%s'\n", soap, a_pszEndpoint )); + + /* we should be initialized but not connected */ + _ASSERTE( pData->hInternet ); + _ASSERTE( !pData->hConnection ); + _ASSERTE( soap->socket == SOAP_INVALID_SOCKET ); + + /* parse out the url path */ + memset( &urlComponents, 0, sizeof(urlComponents) ); + urlComponents.dwStructSize = sizeof(urlComponents); + urlComponents.lpszHostName = szHost; + urlComponents.dwHostNameLength = MAX_PATH; + urlComponents.lpszUrlPath = szUrlPath; + urlComponents.dwUrlPathLength = MAX_PATH; + if ( !InternetCrackUrlA( a_pszEndpoint, 0, 0, &urlComponents ) ) + { + InternetCloseHandle( hConnection ); + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, error %d (%s) in InternetCrackUrl\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + return SOAP_INVALID_SOCKET; + } + + /* connect to the target url, if we haven't connected yet + or if it was dropped */ + hConnection = InternetConnectA( pData->hInternet, + szHost, urlComponents.nPort, "", "", INTERNET_SERVICE_HTTP, + 0, (DWORD_PTR) soap ); + if ( !hConnection ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, error %d (%s) in InternetConnect\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + return SOAP_INVALID_SOCKET; + } + + /* + Note that although we specify HTTP/1.1 for the connection here, the + actual connection may be HTTP/1.0 depending on the settings in the + control panel. See the "Internet Options", "HTTP 1.1 settings". + */ + dwFlags = pData->dwRequestFlags; + if ( soap->omode & SOAP_IO_KEEPALIVE ) + { + dwFlags |= INTERNET_FLAG_KEEP_CONNECTION; + } + if ( urlComponents.nScheme == INTERNET_SCHEME_HTTPS ) + { + dwFlags |= INTERNET_FLAG_SECURE; + } + hHttpRequest = HttpOpenRequestA( + hConnection, "POST", szUrlPath, "HTTP/1.1", NULL, NULL, + dwFlags, (DWORD_PTR) soap ); + if ( !hHttpRequest ) + { + InternetCloseHandle( hConnection ); + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, error %d (%s) in HttpOpenRequest\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + return SOAP_INVALID_SOCKET; + } + + /* save the connection handle in our data structure */ + pData->hConnection = hConnection; + + /* return the http request handle as our file descriptor. */ + _ASSERTE( sizeof(soap->socket) >= sizeof(HINTERNET) ); + return (SOAP_SOCKET) hHttpRequest; +} + +/* gsoap documentation: + Called by http_post and http_response (through the callbacks). Emits HTTP + key: val header entries. Should return SOAP_OK, or a gSOAP error code. + Built-in gSOAP function: http_post_header. + */ +static int +wininet_post_header( + struct soap * soap, + const char * a_pszKey, + const char * a_pszValue ) +{ + HINTERNET hHttpRequest = (HINTERNET) soap->socket; + char szHeader[4096]; + int nLen; + BOOL bResult = FALSE; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + /* ensure that our connection hasn't been disconnected */ + if ( !wininet_have_connection( soap, pData ) ) + { + return SOAP_EOF; + } + + /* if this is the initial POST header then we initialize our send buffer */ + if ( a_pszKey && !a_pszValue ) + { + _ASSERTE( !pData->pBuffer ); + pData->uiBufferLenMax = INVALID_BUFFER_LENGTH; + pData->uiBufferLen = 0; + + /* if we are using chunk output then we start with a chunk size */ + pData->bIsChunkSize = ( (soap->omode & SOAP_IO) == SOAP_IO_CHUNK ); + } + else if ( a_pszValue ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: post_header, adding '%s: %s'\n", + soap, a_pszKey, a_pszValue )); + + /* determine the maximum length of this message so that we can + correctly determine when we have completed the send */ + if ( !strcmp( a_pszKey, "Content-Length" ) ) + { + _ASSERTE( pData->uiBufferLenMax == INVALID_BUFFER_LENGTH ); + pData->uiBufferLenMax = strtoul( a_pszValue, NULL, 10 ); + } + + nLen = _snprintf( + szHeader, 4096, "%s: %s\r\n", a_pszKey, a_pszValue ); + if ( nLen < 0 ) + { + return SOAP_EOM; + } + bResult = HttpAddRequestHeadersA( hHttpRequest, szHeader, nLen, + HTTP_ADDREQ_FLAG_ADD_IF_NEW ); +#ifdef SOAP_DEBUG + /* + we don't return an error if this fails because it isn't + (or shouldn't be) critical. + */ + if ( !bResult ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: post_header, error %d (%s) in HttpAddRequestHeaders\n", + soap, soap->error, wininet_error_message(soap,GetLastError()) )); + } +#endif + } + return SOAP_OK; +} + +/* gsoap documentation: + Called for all send operations to emit contents of s of length n. + Should return SOAP_OK, or a gSOAP error code. Built-in gSOAP + function: fsend + + Notes: + I do a heap of buffering here because we need the entire message available + in a single buffer in order to iterate through the sending loop. I had + hoped that the SOAP_IO_STORE flag would have worked to do the same, however + this still breaks the messages up into blocks. Although there were a number + of ways this could've been implemented, this works and supports all of the + possible SOAP_IO flags, even though the entire message is still buffered + the same as if SOAP_IO_STORE was used. +*/ +static int +wininet_fsend( + struct soap * soap, + const char * a_pBuffer, + size_t a_uiBufferLen ) +{ + HINTERNET hHttpRequest = (HINTERNET) soap->socket; + BOOL bResult; + BOOL bRetryPost; + DWORD dwStatusCode; + DWORD dwStatusCodeLen; + int nResult = SOAP_OK; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, data len = %lu bytes\n", soap, a_uiBufferLen )); + + /* allow the request to be sent with a NULL buffer */ + if (a_uiBufferLen == 0) + { + pData->uiBufferLenMax = 0; + } + + /* ensure that our connection hasn't been disconnected */ + if ( !wininet_have_connection( soap, pData ) ) + { + return SOAP_EOF; + } + + /* initialize on our first time through. pData->pBuffer will always be + non-null if this is not the first call. */ + if ( !pData->pBuffer ) + { + /* + If we are using chunked sending, then we don't know how big the + buffer will need to be. So we start with a 0 length buffer and + grow it later to ensure that it is always large enough. + + uiBufferLenMax = length of the allocated memory + uiBufferLen = length of the data in the buffer + */ + if ( (soap->mode & SOAP_IO) == SOAP_IO_CHUNK ) + { + /* we make the initial allocation large enough for this chunksize + buffer, plus the next chunk of actual data, and a few extra + bytes for the final "0" chunksize block. */ + size_t uiChunkSize = strtoul( a_pBuffer, NULL, 16 ); + pData->uiBufferLenMax = uiChunkSize + a_uiBufferLen + 16; + } + else if ( a_uiBufferLen == pData->uiBufferLenMax ) + { + /* + If the currently supplied buffer from gsoap holds the entire + message then we just use their buffer and avoid any memory + allocation. This will only be true when (1) we are not using + chunked send (so uiBufferLenMax has been previously set to + the Content-Length header length), and (2) gsoap is sending + the entire message at one time. + */ + pData->pBuffer = (char *) a_pBuffer; + pData->uiBufferLen = a_uiBufferLen; + } + + _ASSERTE( pData->uiBufferLenMax != INVALID_BUFFER_LENGTH ); + } + + /* + If we can't use the gsoap buffer, then we need to allocate our own + buffer for the entire message. This is because authentication may + require the entire message to be sent multiple times. Since this send + is only a part of the message, we need to buffer until we have the + entire message. + */ + if ( pData->pBuffer != a_pBuffer ) + { + /* + We already have a buffer pointer, this means that it isn't the + first time we have been called. We have allocated a buffer and + are current filling it. + + If we don't have enough room in the our buffer to add this new + data, then we need to reallocate. This case will only occur with + chunked sends. + */ + size_t uiNewBufferLen = pData->uiBufferLen + a_uiBufferLen; + if ( !pData->pBuffer || uiNewBufferLen > pData->uiBufferLenMax ) + { + while ( uiNewBufferLen > pData->uiBufferLenMax ) + { + pData->uiBufferLenMax = pData->uiBufferLenMax * 2; + } + pData->pBuffer = (char *) realloc( pData->pBuffer, pData->uiBufferLenMax ); + if ( !pData->pBuffer ) + { + return SOAP_EOM; + } + } + memcpy( pData->pBuffer + pData->uiBufferLen, + a_pBuffer, a_uiBufferLen ); + pData->uiBufferLen = uiNewBufferLen; + + /* if we are doing chunked transfers, and this is a chunk size block, + and it is "0", then this is the last block in the transfer and we + can set the maximum size now to continue to the actual send. */ + if ( (soap->mode & SOAP_IO) == SOAP_IO_CHUNK + && pData->bIsChunkSize + && a_pBuffer[2] == '0' && !isalnum(a_pBuffer[3]) ) + { + pData->uiBufferLenMax = pData->uiBufferLen; + } + } + + /* if we haven't got the entire length of the message yet, then + we return to gsoap and let it continue */ + if ( pData->uiBufferLen < pData->uiBufferLenMax ) + { + /* toggle our chunk size marker if we are chunking */ + pData->bIsChunkSize = + ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + && !pData->bIsChunkSize; + return SOAP_OK; + } + _ASSERTE( pData->uiBufferLen == pData->uiBufferLenMax ); + + /* we've now got the entire message, now we can enter our sending loop */ + bRetryPost = TRUE; + while ( bRetryPost ) + { + bRetryPost = FALSE; + + bResult = HttpSendRequestA( + hHttpRequest, NULL, 0, pData->pBuffer, (DWORD)pData->uiBufferLen ); + if ( !bResult ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, error %d (%s) in HttpSendRequest\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + + /* see if we can handle this error, see the MSDN documentation + for InternetErrorDlg for details */ + switch ( soap->error ) + { + case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR: + case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR: + case ERROR_INTERNET_INCORRECT_PASSWORD: + case ERROR_INTERNET_INVALID_CA: + case ERROR_INTERNET_POST_IS_NON_SECURE: + case ERROR_INTERNET_SEC_CERT_CN_INVALID: + case ERROR_INTERNET_SEC_CERT_DATE_INVALID: + case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED: + { + wininet_rseReturn errorResolved = rseDisplayDlg; + if (pData->pRseCallback) + { + errorResolved = pData->pRseCallback(hHttpRequest, soap->error); + } + if (errorResolved == rseDisplayDlg) + { + errorResolved = (wininet_rseReturn) + wininet_resolve_send_error( hHttpRequest, soap->error ); + if ( errorResolved == rseTrue ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, error %d has been resolved\n", + soap, soap->error )); + bRetryPost = TRUE; + + /* + we would have been disconnected by the error. Since we + are going to try again, we will automatically be + reconnected. Therefore we want to disregard any + previous disconnection messages. + */ + pData->bDisconnect = FALSE; + continue; + } + } + } + break; + } + + /* if the error wasn't handled then we exit */ + nResult = SOAP_HTTP_ERROR; + break; + } + + /* get the status code from the response to determine if we need + to authorize */ + dwStatusCodeLen = sizeof(dwStatusCode); + bResult = HttpQueryInfo( + hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, + &dwStatusCode, &dwStatusCodeLen, NULL); + if ( !bResult ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, error %d (%s) in HttpQueryInfo\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + nResult = SOAP_HTTP_ERROR; + break; + } + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, HTTP status code = %lu\n", + soap, dwStatusCode)); + + /* + if we need authentication, then request the user for the + appropriate data. Their reply is saved into the request so + that we can use it later. + */ + switch ( dwStatusCode ) + { + case HTTP_STATUS_DENIED: + case HTTP_STATUS_PROXY_AUTH_REQ: + { + wininet_rseReturn errorResolved = rseDisplayDlg; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, user authenication required\n", + soap )); + if (pData->pRseCallback) + { + errorResolved = pData->pRseCallback(hHttpRequest, dwStatusCode); + } + if (errorResolved == rseDisplayDlg) + { + errorResolved = (wininet_rseReturn) + wininet_resolve_send_error( hHttpRequest, ERROR_INTERNET_INCORRECT_PASSWORD ); + } + if ( errorResolved == rseTrue ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, authentication has been provided\n", + soap )); + + /* + we may have been disconnected by the error. Since we + are going to try again, we will automatically be + reconnected. Therefore we want to disregard any previous + disconnection messages. + */ + pData->bDisconnect = FALSE; + bRetryPost = TRUE; + continue; + } + } + break; + } + } + + /* if we have an allocated buffer then we can deallocate it now */ + if ( pData->pBuffer != a_pBuffer ) + { + free( pData->pBuffer ); + } + + pData->pBuffer = 0; + pData->uiBufferLen = 0; + pData->uiBufferLenMax = INVALID_BUFFER_LENGTH; + + return nResult; +} + +/* gsoap documentation: + Called for all receive operations to fill buffer s of maximum length n. + Should return the number of bytes read or 0 in case of an error, e.g. EOF. + Built-in gSOAP function: frecv + */ +static size_t +wininet_frecv( + struct soap * soap, + char * a_pBuffer, + size_t a_uiBufferLen ) +{ + HINTERNET hHttpRequest = (HINTERNET) soap->socket; + DWORD dwBytesRead = 0; + size_t uiTotalBytesRead = 0; + BOOL bResult; + + soap->error = SOAP_OK; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: frecv, available buffer len = %lu\n", + soap, a_uiBufferLen )); + + /* + NOTE: we do not check here that our connection hasn't been + disconnected because in HTTP/1.0 connections, it will always have been + disconnected by now. This is because the response is checked by the + wininet_fsend function to ensure that we didn't need any special + authentication. At that time the connection would have been + disconnected. This is okay however as we can still read the response + from the request handle. + */ + + do + { + /* read from the connection up to our maximum amount of data */ + _ASSERTE( a_uiBufferLen <= ULONG_MAX ); + bResult = InternetReadFile( + hHttpRequest, + &a_pBuffer[uiTotalBytesRead], + (DWORD) a_uiBufferLen - uiTotalBytesRead, + &dwBytesRead ); + if ( bResult ) + { + uiTotalBytesRead += dwBytesRead; + } + else + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: frecv, error %d (%s) in InternetReadFile\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + } + } + while ( bResult && dwBytesRead && uiTotalBytesRead < a_uiBufferLen ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: recv, received %lu bytes\n", soap, uiTotalBytesRead )); + + return uiTotalBytesRead; +} + +/* gsoap documentation: + Called by client proxy multiple times, to close a socket connection before + a new socket connection is established and at the end of communications + when the SOAP_IO_KEEPALIVE flag is not set and soap.keep_alive = 0 + (indicating that the other party supports keep alive). Should return + SOAP_OK, or a gSOAP error code. Built-in gSOAP function: tcp_disconnect + */ +static int +wininet_disconnect( + struct soap * soap ) +{ + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "wininet %p: disconnect\n", soap )); + + /* force a disconnect by setting the disconnect flag to TRUE */ + pData->bDisconnect = TRUE; + wininet_have_connection( soap, pData ); + + return SOAP_OK; +} + +/* this is mostly for debug tracing */ +void CALLBACK +wininet_callback( + HINTERNET hInternet, + DWORD_PTR dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength ) +{ + struct soap * soap = (struct soap *) dwContext; + + UNUSED_ARG( hInternet ); + UNUSED_ARG( lpvStatusInformation ); + UNUSED_ARG( dwStatusInformationLength ); + + switch ( dwInternetStatus ) + { + case INTERNET_STATUS_RESOLVING_NAME: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_RESOLVING_NAME\n", soap )); + break; + case INTERNET_STATUS_NAME_RESOLVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_NAME_RESOLVED\n", soap )); + break; + case INTERNET_STATUS_CONNECTING_TO_SERVER: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CONNECTING_TO_SERVER\n", soap)); + break; + case INTERNET_STATUS_CONNECTED_TO_SERVER: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CONNECTED_TO_SERVER\n", soap)); + break; + case INTERNET_STATUS_SENDING_REQUEST: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_SENDING_REQUEST\n", soap)); + break; + case INTERNET_STATUS_REQUEST_SENT: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_REQUEST_SENT, bytes sent = %lu\n", + soap, *(DWORD *)lpvStatusInformation )); + break; + case INTERNET_STATUS_RECEIVING_RESPONSE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_RECEIVING_RESPONSE\n", soap)); + break; + case INTERNET_STATUS_RESPONSE_RECEIVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_RESPONSE_RECEIVED, bytes received = %lu\n", + soap, *(DWORD *)lpvStatusInformation )); + break; + case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CTL_RESPONSE_RECEIVED\n", soap)); + break; + case INTERNET_STATUS_PREFETCH: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_PREFETCH\n", soap)); + break; + case INTERNET_STATUS_CLOSING_CONNECTION: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CLOSING_CONNECTION\n", soap)); + break; + case INTERNET_STATUS_CONNECTION_CLOSED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CONNECTION_CLOSED\n", soap)); + { + /* the connection has been closed, so we close the handle here */ + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + if ( pData->hConnection ) + { + /* + we only mark this for disconnection otherwise we get + errors when reading the data from the handle. In every + function that we use the connection we will check first to + see if it has been disconnected. + */ + pData->bDisconnect = TRUE; + } + } + break; + case INTERNET_STATUS_HANDLE_CREATED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_HANDLE_CREATED\n", soap)); + break; + case INTERNET_STATUS_HANDLE_CLOSING: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_HANDLE_CLOSING\n", soap)); + break; +#ifdef INTERNET_STATUS_DETECTING_PROXY + case INTERNET_STATUS_DETECTING_PROXY: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_DETECTING_PROXY\n", soap)); + break; +#endif + case INTERNET_STATUS_REQUEST_COMPLETE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_REQUEST_COMPLETE\n", soap)); + break; + case INTERNET_STATUS_REDIRECT: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_REDIRECT, new url = %s\n", + soap, (char*) lpvStatusInformation )); + break; + case INTERNET_STATUS_INTERMEDIATE_RESPONSE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_INTERMEDIATE_RESPONSE\n", soap)); + break; +#ifdef INTERNET_STATUS_USER_INPUT_REQUIRED + case INTERNET_STATUS_USER_INPUT_REQUIRED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_USER_INPUT_REQUIRED\n", soap)); + break; +#endif + case INTERNET_STATUS_STATE_CHANGE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_STATE_CHANGE\n", soap)); + break; +#ifdef INTERNET_STATUS_COOKIE_SENT + case INTERNET_STATUS_COOKIE_SENT: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_COOKIE_SENT\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_COOKIE_RECEIVED + case INTERNET_STATUS_COOKIE_RECEIVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_COOKIE_RECEIVED\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_PRIVACY_IMPACTED + case INTERNET_STATUS_PRIVACY_IMPACTED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_PRIVACY_IMPACTED\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_P3P_HEADER + case INTERNET_STATUS_P3P_HEADER: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_P3P_HEADER\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_P3P_POLICYREF + case INTERNET_STATUS_P3P_POLICYREF: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_P3P_POLICYREF\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_COOKIE_HISTORY + case INTERNET_STATUS_COOKIE_HISTORY: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_COOKIE_HISTORY\n", soap)); + break; +#endif + } +} + +/* + check to ensure that our connection hasn't been disconnected + and disconnect remaining handles if necessary. + */ +static BOOL +wininet_have_connection( + struct soap * soap, + struct wininet_data * a_pData ) +{ + /* close the http request if we don't have a connection */ + BOOL bCloseRequest = a_pData->bDisconnect || !a_pData->hConnection; + if ( bCloseRequest && soap->socket != SOAP_INVALID_SOCKET ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: closing request\n", soap)); + + InternetCloseHandle( (HINTERNET) soap->socket ); + soap->socket = SOAP_INVALID_SOCKET; + } + + /* close the connection if we don't have a request */ + if ( soap->socket == SOAP_INVALID_SOCKET && a_pData->hConnection ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: closing connection\n", soap)); + + InternetCloseHandle( a_pData->hConnection ); + a_pData->hConnection = NULL; + } + a_pData->bDisconnect = FALSE; + + /* clean up the send details if we don't have a request */ + if ( soap->socket == SOAP_INVALID_SOCKET ) + { + if ( a_pData->pBuffer ) + { + free( a_pData->pBuffer ); + a_pData->pBuffer = 0; + } + a_pData->uiBufferLen = 0; + a_pData->uiBufferLenMax = INVALID_BUFFER_LENGTH; + } + + /* we now either still have both request and connection, or neither */ + return (a_pData->hConnection != NULL); +} + +static DWORD +wininet_set_timeout( + struct soap * soap, + struct wininet_data * a_pData, + const char * a_pszTimeout, + DWORD a_dwOption, + int a_nTimeout ) +{ + UNUSED_ARG( soap ); + UNUSED_ARG( a_pszTimeout ); + + if ( a_nTimeout > 0 ) + { + DWORD dwTimeout = a_nTimeout * 1000; + if ( !InternetSetOption( a_pData->hInternet, + a_dwOption, &dwTimeout, sizeof(DWORD) ) ) + { + DWORD dwErrorCode = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: failed to set %s timeout, error %d (%s)\n", + soap, a_pszTimeout, dwErrorCode, + wininet_error_message(soap,dwErrorCode) )); + return dwErrorCode; + } + } + return 0; +} + +/* +static BOOL +wininet_flag_set_option( + HINTERNET a_hHttpRequest, + DWORD a_dwOption, + DWORD a_dwFlag ) +{ + DWORD dwBuffer; + DWORD dwBufferLength = sizeof(DWORD); + + BOOL bSuccess = InternetQueryOption( + a_hHttpRequest, + a_dwOption, + &dwBuffer, + &dwBufferLength ); + if (bSuccess) { + dwBuffer |= a_dwFlag; + bSuccess = InternetSetOption( + a_hHttpRequest, + a_dwOption, + &dwBuffer, + dwBufferLength); + } +#ifdef SOAP_DEBUG + if ( !bSuccess ) { + DWORD dwErrorCode = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: failed to set option: %X, error %d (%s)\n", + a_hHttpRequest, a_dwOption, dwErrorCode, + wininet_error_message(soap,dwErrorCode) )); + } +#endif + return bSuccess; +} +*/ + +static BOOL +wininet_resolve_send_error( + HINTERNET a_hHttpRequest, + DWORD a_dwErrorCode ) +{ + DWORD dwResult = InternetErrorDlg( + GetDesktopWindow(), + a_hHttpRequest, + a_dwErrorCode, + FLAGS_ERROR_UI_FILTER_FOR_ERRORS | + FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | + FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, + NULL ); + BOOL bRetVal = (a_dwErrorCode == ERROR_INTERNET_INCORRECT_PASSWORD) ? + (dwResult == ERROR_INTERNET_FORCE_RETRY) : + (dwResult == ERROR_SUCCESS); + /* If appropriate for your application, it is possible to ignore + errors in future once they have been handled or ignored once. + For example, to ignore invalid SSL certificate dates on this + connection once the client has indicated to ignore them this + time, uncomment this code. + */ + /* + if (bRetVal) + { + switch (a_dwErrorCode) + { + case ERROR_INTERNET_SEC_CERT_CN_INVALID: + wininet_flag_set_option(a_hHttpRequest, + INTERNET_OPTION_SECURITY_FLAGS, + SECURITY_FLAG_IGNORE_CERT_CN_INVALID ); + break; + } + } + */ + return bRetVal; + +} + +#ifdef SOAP_DEBUG + +static const char * +wininet_error_message( + struct soap * soap, + DWORD a_dwErrorMsgId ) +{ + HINSTANCE hModule; + DWORD dwResult; + DWORD dwFormatFlags; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + /* free any existing error message */ + wininet_free_error_message( pData ); + + dwFormatFlags = + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM; + + /* load wininet.dll for the error messages */ + hModule = LoadLibraryExA( "wininet.dll", NULL, + LOAD_LIBRARY_AS_DATAFILE | DONT_RESOLVE_DLL_REFERENCES ); + if ( hModule ) + { + dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE; + } + + /* format the messages */ + dwResult = FormatMessageA( + dwFormatFlags, + hModule, + a_dwErrorMsgId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &pData->pszErrorMessage, + 0, + NULL ); + + /* free the library if we loaded it */ + if ( hModule ) + { + FreeLibrary( hModule ); + } + + /* remove the CR LF from the error message */ + if ( dwResult > 2 ) + { + pData->pszErrorMessage[dwResult-2] = 0; + return pData->pszErrorMessage; + } + else + { + const static char szUnknown[] = "(unknown)"; + return szUnknown; + } +} + +static void +wininet_free_error_message( + struct wininet_data * a_pData ) +{ + if ( a_pData->pszErrorMessage ) + { + LocalFree( a_pData->pszErrorMessage ); + a_pData->pszErrorMessage = 0; + } +} + +#endif /* SOAP_DEBUG */ diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.cpp b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.cpp new file mode 100644 index 000000000..a84db704f --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.cpp @@ -0,0 +1,1432 @@ +/* +See the header file for details. This file is distributed under the MIT licence. +*/ + +/* system */ +#include +#include +#include + +/* gsoap */ +#include + +/* local */ +#include "gsoapWinInet.h" + +/* ensure that the wininet library is linked */ +#pragma comment( lib, "wininet.lib" ) +/* disable deprecation warnings */ +#pragma warning(disable : 4996) + +#define UNUSED_ARG(x) (x) +#define INVALID_BUFFER_LENGTH ((DWORD)-1) + +/* plugin id */ +static const char wininet_id[] = "wininet-2.0"; + +/* plugin private data */ +struct wininet_data +{ + HINTERNET hInternet; /* internet session handle */ + HINTERNET hConnection; /* current connection handle */ + BOOL bDisconnect; /* connection is disconnected */ + BOOL bKeepAlive; /* keep connection alive */ + DWORD dwRequestFlags; /* extra request flags from user */ + char * pBuffer; /* send buffer */ + size_t uiBufferLenMax; /* total length of the message */ + size_t uiBufferLen; /* length of data in buffer */ + BOOL bIsChunkSize; /* expecting a chunk size buffer */ + wininet_rse_callback pRseCallback; /* wininet_resolve_send_error callback. Allows clients to resolve ssl errors programatically */ + wininet_progress_callback pProgressCallback; /* callback to report a progress */ + LPVOID pProgressCallbackContext; /* context for pProgressCallback */ + char * pRespHeaders; /* buffer for response headers */ + size_t uiRespHeadersLen; /* length of data in response headers buffer */ + size_t uiRespHeadersReaded;/* length of data readed from response headers buffer */ + char * pszErrorMessage; /* wininet/system error message */ +}; + +#if 1 +#define Trace(pszFunc, pBuffer, uiBufferLen) \ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "wininet %p: %s 0x%p %d\n", soap, pszFunc, pBuffer, uiBufferLen)); +#else +void Trace(const char* pszFunc, const void* pBuffer, DWORD uiBufferLen) +{ +/* + static bool newOne = true; + FILE* f = fopen("C:\\log.log", newOne ? "wt" : "at"); + newOne = false; + if (f) + { + fprintf(f, "\n============================================\n%s:\n", pszFunc); + if (pBuffer) + fwrite(pBuffer, uiBufferLen, 1, f); + fclose(f); + } +*/ +} +#endif + +/* forward declarations */ +static BOOL +wininet_init( + struct soap * soap, + struct wininet_data * a_pData, + DWORD a_dwRequestFlags ); +static int +wininet_copy( + struct soap * soap, + struct soap_plugin * a_pDst, + struct soap_plugin * a_pSrc ); +static void +wininet_delete( + struct soap * soap, + struct soap_plugin * a_pPluginData ); +static SOAP_SOCKET +wininet_connect( + struct soap * soap, + const char * a_pszEndpoint, + const char * a_pszHost, + int a_nPort ); +static int +wininet_post_header( + struct soap * soap, + const char * a_pszKey, + const char * a_pszValue ); +static int +wininet_fsend( + struct soap * soap, + const char * a_pBuffer, + size_t a_uiBufferLen ); +static size_t +wininet_frecv( + struct soap * soap, + char * a_pBuffer, + size_t a_uiBufferLen ); +static int +wininet_disconnect( + struct soap * soap ); +void CALLBACK +wininet_callback( + HINTERNET hInternet, + DWORD_PTR dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength ); +static BOOL +wininet_have_connection( + struct soap * soap, + struct wininet_data * a_pData ); +static int +wininet_fpoll( + struct soap * soap ); +static DWORD +wininet_set_timeout( + struct soap * soap, + struct wininet_data * a_pData, + const char * a_pszTimeout, + DWORD a_dwOption, + int a_nTimeout ); +static BOOL +wininet_resolve_send_error( + HINTERNET a_hHttpRequest, + DWORD a_dwErrorCode ); +static const char * +wininet_error_message( + struct soap * a_pData, + DWORD a_dwErrorMsgId ); +static void +wininet_free_error_message( + struct wininet_data * a_pData ); + +/* plugin registration */ +int +wininet_plugin( + struct soap * soap, + struct soap_plugin * a_pPluginData, + void * a_dwRequestFlags ) +{ + if ( !soap ) + return SOAP_FATAL_ERROR; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: plugin registration\n", soap )); + + a_pPluginData->id = wininet_id; + a_pPluginData->fcopy = wininet_copy; + a_pPluginData->fdelete = wininet_delete; + a_pPluginData->data = (void*) malloc( sizeof(struct wininet_data) ); + if ( !a_pPluginData->data ) + { + return SOAP_EOM; + } + if ( !wininet_init( soap, + (struct wininet_data *) a_pPluginData->data, + (DWORD) (size_t) a_dwRequestFlags ) ) + { + free( a_pPluginData->data ); + return SOAP_EOM; + } + +#ifdef SOAP_DEBUG + if ( (soap->omode & SOAP_IO) == SOAP_IO_STORE ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: use of SOAP_IO_STORE is not recommended\n", soap )); + } +#endif + + return SOAP_OK; +} + +/* initialize private data */ +static BOOL +wininet_init( + struct soap * soap, + struct wininet_data * a_pData, + DWORD a_dwRequestFlags ) +{ + if ( !soap ) + return SOAP_FATAL_ERROR; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: init private data\n", soap )); + + memset( a_pData, 0, sizeof(struct wininet_data) ); + a_pData->dwRequestFlags = a_dwRequestFlags; + + Trace("InternetOpenA", 0, 0); + + /* start our internet session */ + a_pData->hInternet = InternetOpenA( + "gSOAP", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); + if ( !a_pData->hInternet ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: init, error %d (%s) in InternetOpen\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + wininet_free_error_message( a_pData ); + return FALSE; + } + + /* set the timeouts, if any of these fail the error isn't fatal */ + wininet_set_timeout( soap, a_pData, "connect", + INTERNET_OPTION_CONNECT_TIMEOUT, soap->connect_timeout ); + wininet_set_timeout( soap, a_pData, "receive", + INTERNET_OPTION_RECEIVE_TIMEOUT, soap->recv_timeout ); + wininet_set_timeout( soap, a_pData, "send", + INTERNET_OPTION_SEND_TIMEOUT, soap->send_timeout ); + + /* set up the callback function so we get notifications */ + InternetSetStatusCallback( a_pData->hInternet, wininet_callback ); + + /* set all of our callbacks */ + soap->fopen = wininet_connect; + soap->fposthdr = wininet_post_header; + soap->fsend = wininet_fsend; + soap->frecv = wininet_frecv; + soap->fclose = wininet_disconnect; + soap->fpoll = wininet_fpoll; + + return TRUE; +} + +void +wininet_set_rse_callback( + struct soap * soap, + wininet_rse_callback a_pRsecallback) +{ + struct wininet_data * pData = (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: resolve_send_error callback = '%p'\n", soap, a_pRsecallback )); + + pData->pRseCallback = a_pRsecallback; +} + +void +wininet_set_progress_callback( + struct soap * soap, + wininet_progress_callback a_pProgressCallback, + LPVOID a_pContext) +{ + struct wininet_data * pData = (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: progress callback = '%p', context = '%p'\n", soap, a_pProgressCallback, a_pContext )); + + pData->pProgressCallback = a_pProgressCallback; + pData->pProgressCallbackContext = a_pContext; +} + +/* copy the private data structure */ +static int +wininet_copy( + struct soap * soap, + struct soap_plugin * a_pDst, + struct soap_plugin * a_pSrc ) +{ + UNUSED_ARG( soap ); + UNUSED_ARG( a_pDst ); + UNUSED_ARG( a_pSrc ); + + _ASSERTE( !"wininet doesn't support copy" ); + return SOAP_FATAL_ERROR; +} + +/* deallocate of our private structure */ +static void +wininet_delete( + struct soap * soap, + struct soap_plugin * a_pPluginData ) +{ + struct wininet_data * pData = + (struct wininet_data *) a_pPluginData->data; + + UNUSED_ARG( soap ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: delete private data\n", soap )); + + /* force a disconnect of any existing connection */ + pData->bDisconnect = TRUE; + wininet_have_connection( soap, pData ); + + /* close down the internet */ + if ( pData->hInternet ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: closing internet handle\n", soap)); + InternetCloseHandle( pData->hInternet ); + pData->hInternet = NULL; + } + + /* free our data */ + wininet_free_error_message( pData ); + free( a_pPluginData->data ); +} + +/* gsoap documentation: + Called from a client proxy to open a connection to a Web Service located + at endpoint. Input parameters host and port are micro-parsed from endpoint. + Should return a valid file descriptor, or SOAP_INVALID_SOCKET and + soap->error set to an error code. Built-in gSOAP function: tcp_connect +*/ +static SOAP_SOCKET +wininet_connect( + struct soap * soap, + const char * a_pszEndpoint, + const char * a_pszHost, + int a_nPort ) +{ + URL_COMPONENTSA urlComponents; + char szUrlPath[MAX_PATH] = {0}; + char szHost[MAX_PATH] = {0}; + DWORD dwFlags; + HINTERNET hConnection = NULL; + HINTERNET hHttpRequest = NULL; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + /* we parse the URL ourselves so we don't use these parameters */ + UNUSED_ARG( a_pszHost ); + UNUSED_ARG( a_nPort ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, endpoint = '%s'\n", soap, a_pszEndpoint )); + + /* we should be initialized but not connected */ + _ASSERTE( pData->hInternet ); + if ( !pData->hInternet ) + return SOAP_FATAL_ERROR; + _ASSERTE( !pData->bKeepAlive && !pData->hConnection || pData->bKeepAlive && pData->hConnection ); + if ( !(!pData->bKeepAlive && !pData->hConnection || pData->bKeepAlive && pData->hConnection) ) + return SOAP_FATAL_ERROR; + _ASSERTE( soap->socket == SOAP_INVALID_SOCKET ); + if ( soap->socket != SOAP_INVALID_SOCKET ) + return SOAP_FATAL_ERROR; + + /* parse out the url path */ + memset( &urlComponents, 0, sizeof(urlComponents) ); + urlComponents.dwStructSize = sizeof(urlComponents); + urlComponents.lpszHostName = szHost; + urlComponents.dwHostNameLength = MAX_PATH; + urlComponents.lpszUrlPath = szUrlPath; + urlComponents.dwUrlPathLength = MAX_PATH; + if ( !InternetCrackUrlA( a_pszEndpoint, 0, 0, &urlComponents ) ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, error %d (%s) in InternetCrackUrl\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + return SOAP_INVALID_SOCKET; + } + + if ( !pData->hConnection ) + { + Trace("InternetConnectA", szHost, (DWORD)strlen(szHost)); + + /* connect to the target url, if we haven't connected yet + or if it was dropped */ + hConnection = InternetConnectA( pData->hInternet, + szHost, urlComponents.nPort, "", "", INTERNET_SERVICE_HTTP, + 0, (DWORD_PTR) soap ); + if ( !hConnection ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, error %d (%s) in InternetConnect\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + return SOAP_INVALID_SOCKET; + } + } + else + { + hConnection = pData->hConnection; + pData->hConnection = NULL; + } + + /* + Note that although we specify HTTP/1.1 for the connection here, the + actual connection may be HTTP/1.0 depending on the settings in the + control panel. See the "Internet Options", "HTTP 1.1 settings". + */ + dwFlags = pData->dwRequestFlags | INTERNET_FLAG_NO_CACHE_WRITE; + if ( soap->omode & SOAP_IO_KEEPALIVE ) + { + dwFlags |= INTERNET_FLAG_KEEP_CONNECTION; + pData->bKeepAlive = TRUE; + } + if ( urlComponents.nScheme == INTERNET_SCHEME_HTTPS ) + { + dwFlags |= INTERNET_FLAG_SECURE; + } + + Trace("HttpOpenRequestA", szUrlPath, (DWORD)strlen(szUrlPath)); + + hHttpRequest = HttpOpenRequestA( + hConnection, "POST", szUrlPath, "HTTP/1.1", NULL, NULL, + dwFlags, (DWORD_PTR) soap ); + if ( !hHttpRequest ) + { + InternetCloseHandle( hConnection ); + pData->bKeepAlive = FALSE; + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: connect, error %d (%s) in HttpOpenRequest\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + wininet_free_error_message(pData); + return SOAP_INVALID_SOCKET; + } + + /* save the connection handle in our data structure */ + pData->hConnection = hConnection; + + /* return the http request handle as our file descriptor. */ + _ASSERTE( sizeof(soap->socket) >= sizeof(HINTERNET) ); + return (SOAP_SOCKET) hHttpRequest; +} + +/* gsoap documentation: + Called by http_post and http_response (through the callbacks). Emits HTTP + key: val header entries. Should return SOAP_OK, or a gSOAP error code. + Built-in gSOAP function: http_post_header. + */ +static int +wininet_post_header( + struct soap * soap, + const char * a_pszKey, + const char * a_pszValue ) +{ + HINTERNET hHttpRequest = (HINTERNET) soap->socket; + char szHeader[4096]; + int nLen; + BOOL bResult = FALSE; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + /* ensure that our connection hasn't been disconnected */ + if ( !wininet_have_connection( soap, pData ) ) + { + return SOAP_EOF; + } + + /* if this is the initial POST header then we initialize our send buffer */ + if ( a_pszKey && !a_pszValue ) + { + _ASSERTE( !pData->pBuffer ); + pData->uiBufferLenMax = INVALID_BUFFER_LENGTH; + pData->uiBufferLen = 0; + + /* if we are using chunk output then we start with a chunk size */ + pData->bIsChunkSize = ( (soap->omode & SOAP_IO) == SOAP_IO_CHUNK ); + } + else if ( a_pszValue ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: post_header, adding '%s: %s'\n", + soap, a_pszKey, a_pszValue )); + + /* determine the maximum length of this message so that we can + correctly determine when we have completed the send */ + if ( !strcmp( a_pszKey, "Content-Length" ) ) + { + _ASSERTE( pData->uiBufferLenMax == INVALID_BUFFER_LENGTH ); + pData->uiBufferLenMax = strtoul( a_pszValue, NULL, 10 ); + } + + nLen = _snprintf( + szHeader, 4096, "%s: %s\r\n", a_pszKey, a_pszValue ); + if ( nLen < 0 ) + { + return SOAP_EOM; + } + + Trace("HttpAddRequestHeadersA", szHeader, nLen); + + bResult = HttpAddRequestHeadersA( hHttpRequest, szHeader, nLen, + HTTP_ADDREQ_FLAG_ADD_IF_NEW ); +#ifdef SOAP_DEBUG + /* + we don't return an error if this fails because it isn't + (or shouldn't be) critical. + */ + if ( !bResult ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: post_header, error %d (%s) in HttpAddRequestHeaders\n", + soap, soap->error, wininet_error_message(soap,GetLastError()) )); + } +#endif + } + return SOAP_OK; +} + +/* gsoap documentation: + Called for all send operations to emit contents of s of length n. + Should return SOAP_OK, or a gSOAP error code. Built-in gSOAP + function: fsend + + Notes: + I do a heap of buffering here because we need the entire message available + in a single buffer in order to iterate through the sending loop. I had + hoped that the SOAP_IO_STORE flag would have worked to do the same, however + this still breaks the messages up into blocks. Although there were a number + of ways this could've been implemented, this works and supports all of the + possible SOAP_IO flags, even though the entire message is still buffered + the same as if SOAP_IO_STORE was used. +*/ +static int +wininet_fsend( + struct soap * soap, + const char * a_pBuffer, + size_t a_uiBufferLen ) +{ + HINTERNET hHttpRequest = (HINTERNET) soap->socket; + BOOL bResult; + BOOL bRetryPost; + DWORD dwStatusCode; + DWORD dwStatusCodeLen; + int nResult = SOAP_OK; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, data len = %lu bytes\n", soap, a_uiBufferLen )); + + /* allow the request to be sent with a NULL buffer */ + if (a_uiBufferLen == 0) + { + pData->uiBufferLenMax = 0; + } + + /* ensure that our connection hasn't been disconnected */ + if ( !wininet_have_connection( soap, pData ) ) + { + return SOAP_EOF; + } + + /* initialize on our first time through. pData->pBuffer will always be + non-null if this is not the first call. */ + if ( !pData->pBuffer ) + { + /* + If we are using chunked sending, then we don't know how big the + buffer will need to be. So we start with a 0 length buffer and + grow it later to ensure that it is always large enough. + + uiBufferLenMax = length of the allocated memory + uiBufferLen = length of the data in the buffer + */ + if ( (soap->mode & SOAP_IO) == SOAP_IO_CHUNK ) + { + /* we make the initial allocation large enough for this chunksize + buffer, plus the next chunk of actual data, and a few extra + bytes for the final "0" chunksize block. */ + size_t uiChunkSize = strtoul( a_pBuffer, NULL, 16 ); + pData->uiBufferLenMax = uiChunkSize + a_uiBufferLen + 16; + } + else if ( a_uiBufferLen == pData->uiBufferLenMax ) + { + /* + If the currently supplied buffer from gsoap holds the entire + message then we just use their buffer and avoid any memory + allocation. This will only be true when (1) we are not using + chunked send (so uiBufferLenMax has been previously set to + the Content-Length header length), and (2) gsoap is sending + the entire message at one time. + */ + pData->pBuffer = (char *) a_pBuffer; + pData->uiBufferLen = a_uiBufferLen; + } + + _ASSERTE( pData->uiBufferLenMax != INVALID_BUFFER_LENGTH ); + } + + /* + If we can't use the gsoap buffer, then we need to allocate our own + buffer for the entire message. This is because authentication may + require the entire message to be sent multiple times. Since this send + is only a part of the message, we need to buffer until we have the + entire message. + */ + if ( pData->pBuffer != a_pBuffer ) + { + /* + We already have a buffer pointer, this means that it isn't the + first time we have been called. We have allocated a buffer and + are current filling it. + + If we don't have enough room in the our buffer to add this new + data, then we need to reallocate. This case will only occur with + chunked sends. + */ + size_t uiNewBufferLen = pData->uiBufferLen + a_uiBufferLen; + if ( !pData->pBuffer || uiNewBufferLen > pData->uiBufferLenMax ) + { + while ( uiNewBufferLen > pData->uiBufferLenMax ) + { + pData->uiBufferLenMax = pData->uiBufferLenMax * 2; + } + char *pReallocatedBuffer = (char *) realloc( pData->pBuffer, pData->uiBufferLenMax ); + if ( !pReallocatedBuffer ) + { + return SOAP_EOM; + } + pData->pBuffer = pReallocatedBuffer; + } + memcpy( pData->pBuffer + pData->uiBufferLen, + a_pBuffer, a_uiBufferLen ); + pData->uiBufferLen = uiNewBufferLen; + + /* if we are doing chunked transfers, and this is a chunk size block, + and it is "0", then this is the last block in the transfer and we + can set the maximum size now to continue to the actual send. */ + if ( (soap->mode & SOAP_IO) == SOAP_IO_CHUNK + && pData->bIsChunkSize + && a_pBuffer[2] == '0' && !isalnum((unsigned char)a_pBuffer[3]) ) + { + pData->uiBufferLenMax = pData->uiBufferLen; + } + } + + /* if we haven't got the entire length of the message yet, then + we return to gsoap and let it continue */ + if ( pData->uiBufferLen < pData->uiBufferLenMax ) + { + /* toggle our chunk size marker if we are chunking */ + pData->bIsChunkSize = + ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + && !pData->bIsChunkSize; + return SOAP_OK; + } + _ASSERTE( pData->uiBufferLen == pData->uiBufferLenMax ); + + /* we've now got the entire message, now we can enter our sending loop */ + bRetryPost = TRUE; + while ( bRetryPost ) + { + bRetryPost = FALSE; + + /* to report a progress when sending a big buffer we need to send it by small + chunks since INTERNET_STATUS_REQUEST_SENT callback is sent for entire buffer */ + const DWORD dwChunkSize = 64 * 1024; + if ( pData->pProgressCallback && (DWORD)pData->uiBufferLen > dwChunkSize ) + { + INTERNET_BUFFERSA buffer; + memset(&buffer, 0, sizeof(buffer)); + buffer.dwStructSize = sizeof(buffer); + buffer.lpvBuffer = pData->pBuffer; + buffer.dwBufferLength = min((DWORD)pData->uiBufferLen, dwChunkSize); + buffer.dwBufferTotal = (DWORD)pData->uiBufferLen; + Trace("HttpSendRequestExA", pData->pBuffer, buffer.dwBufferLength); + bResult = HttpSendRequestExA( hHttpRequest, &buffer, NULL, 0, 0 ); + while ( bResult && buffer.dwBufferLength < buffer.dwBufferTotal ) + { + DWORD bytesWritten = min(buffer.dwBufferTotal - buffer.dwBufferLength, dwChunkSize); + Trace("InternetWriteFile", pData->pBuffer + buffer.dwBufferLength, bytesWritten); + bResult = InternetWriteFile( hHttpRequest, pData->pBuffer + buffer.dwBufferLength, bytesWritten, &bytesWritten ); + buffer.dwBufferLength += bytesWritten; + } + if ( bResult ) + { + bResult = HttpEndRequestA( hHttpRequest, NULL, 0, 0 ); + } + } + else + { + Trace("HttpSendRequestA", pData->pBuffer, (DWORD)pData->uiBufferLen); + + bResult = HttpSendRequestA( + hHttpRequest, NULL, 0, pData->pBuffer, (DWORD)pData->uiBufferLen ); + } + if ( !bResult ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, error %d (%s) in HttpSendRequest\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + + /* see if we can handle this error, see the MSDN documentation + for InternetErrorDlg for details */ + switch ( soap->error ) + { + case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR: + case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR: + case ERROR_INTERNET_INCORRECT_PASSWORD: + case ERROR_INTERNET_INVALID_CA: + case ERROR_INTERNET_POST_IS_NON_SECURE: + case ERROR_INTERNET_SEC_CERT_CN_INVALID: + case ERROR_INTERNET_SEC_CERT_DATE_INVALID: + case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED: + { + wininet_rseReturn errorResolved = rseDisplayDlg; + if (pData->pRseCallback) + { + errorResolved = pData->pRseCallback(hHttpRequest, soap->error); + } + if (errorResolved == rseDisplayDlg) + { + errorResolved = (wininet_rseReturn) + wininet_resolve_send_error( hHttpRequest, soap->error ); + if ( errorResolved == rseTrue ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, error %d has been resolved\n", + soap, soap->error )); + bRetryPost = TRUE; + + /* + we would have been disconnected by the error. Since we + are going to try again, we will automatically be + reconnected. Therefore we want to disregard any + previous disconnection messages. + */ + pData->bDisconnect = FALSE; + continue; + } + } + } + break; + } + + /* if the error wasn't handled then we exit */ + switch ( soap->error ) + { + case ERROR_INTERNET_CANNOT_CONNECT: + nResult = SOAP_TCP_ERROR; + default: + nResult = SOAP_HTTP_ERROR; + } + soap_set_sender_error(soap, "HttpSendRequest failed", wininet_error_message(soap,soap->error), nResult); + break; + } + + /* get the status code from the response to determine if we need + to authorize */ + dwStatusCodeLen = sizeof(dwStatusCode); + Trace("HttpQueryInfo - wininet_fsend", 0, 0); + bResult = HttpQueryInfo( + hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, + &dwStatusCode, &dwStatusCodeLen, NULL); + + char buf[1024];dwStatusCodeLen = sizeof(buf); + bResult = HttpQueryInfo( + hHttpRequest, HTTP_QUERY_STATUS_TEXT, + buf, &dwStatusCodeLen, NULL); + + if ( !bResult ) + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, error %d (%s) in HttpQueryInfo\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + nResult = SOAP_HTTP_ERROR; + break; + } + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, HTTP status code = %lu\n", + soap, dwStatusCode)); + + /* + if we need authentication, then request the user for the + appropriate data. Their reply is saved into the request so + that we can use it later. + */ + switch ( dwStatusCode ) + { + case HTTP_STATUS_DENIED: + case HTTP_STATUS_PROXY_AUTH_REQ: + { + wininet_rseReturn errorResolved = rseDisplayDlg; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, user authenication required\n", + soap )); + if (pData->pRseCallback) + { + errorResolved = pData->pRseCallback(hHttpRequest, dwStatusCode); + } + if (errorResolved == rseDisplayDlg) + { + errorResolved = (wininet_rseReturn) + wininet_resolve_send_error( hHttpRequest, ERROR_INTERNET_INCORRECT_PASSWORD ); + } + if ( errorResolved == rseTrue ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: fsend, authentication has been provided\n", + soap )); + + /* + we may have been disconnected by the error. Since we + are going to try again, we will automatically be + reconnected. Therefore we want to disregard any previous + disconnection messages. + */ + pData->bDisconnect = FALSE; + bRetryPost = TRUE; + continue; + } + } + break; + } + } + + /* if we have an allocated buffer then we can deallocate it now */ + if ( pData->pBuffer != a_pBuffer ) + { + free( pData->pBuffer ); + } + + pData->pBuffer = 0; + pData->uiBufferLen = 0; + pData->uiBufferLenMax = INVALID_BUFFER_LENGTH; + + pData->pRespHeaders = 0; + + return nResult; +} + +/* gsoap documentation: + Called for all receive operations to fill buffer s of maximum length n. + Should return the number of bytes read or 0 in case of an error, e.g. EOF. + Built-in gSOAP function: frecv + */ +static size_t +wininet_frecv( + struct soap * soap, + char * a_pBuffer, + size_t a_uiBufferLen ) +{ + HINTERNET hHttpRequest = (HINTERNET) soap->socket; + DWORD dwBytesRead = 0; + size_t uiTotalBytesRead = 0; + BOOL bResult; + + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + if (!pData->pRespHeaders) + { + DWORD size = 0; + +retry: + // This call will fail on the first pass, because no buffer is allocated. + if (!HttpQueryInfo(hHttpRequest, HTTP_QUERY_RAW_HEADERS_CRLF, + (LPVOID)pData->pRespHeaders, &size, NULL)) + { + // Check for an insufficient buffer. + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + // Allocate the necessary buffer. + pData->pRespHeaders = (char*) malloc(size); + + // Retry the call. + goto retry; + } + else + { + pData->pRespHeaders = (char*) malloc(0); + pData->uiRespHeadersLen = 0; + pData->uiRespHeadersReaded = 0; + Trace("HttpQueryInfo - no headers", 0, 0); + } + } + else + { + pData->uiRespHeadersLen = size; + pData->uiRespHeadersReaded = 0; + Trace("HttpQueryInfo - reading headers", pData->pRespHeaders, static_cast(pData->uiRespHeadersLen)); + } + } + + if (pData->pRespHeaders && pData->uiRespHeadersReaded < pData->uiRespHeadersLen) + { + size_t notReceivedPart = pData->uiRespHeadersLen - pData->uiRespHeadersReaded; + size_t recvSize = min(a_uiBufferLen, notReceivedPart); + + memcpy(a_pBuffer, pData->pRespHeaders + pData->uiRespHeadersReaded, recvSize); + pData->uiRespHeadersReaded += recvSize; + if (a_uiBufferLen == recvSize) + return a_uiBufferLen; + uiTotalBytesRead = recvSize; + } + + soap->error = SOAP_OK; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: frecv, available buffer len = %lu\n", + soap, a_uiBufferLen )); + + /* + NOTE: we do not check here that our connection hasn't been + disconnected because in HTTP/1.0 connections, it will always have been + disconnected by now. This is because the response is checked by the + wininet_fsend function to ensure that we didn't need any special + authentication. At that time the connection would have been + disconnected. This is okay however as we can still read the response + from the request handle. + */ + + do + { + /* read from the connection up to our maximum amount of data */ + _ASSERTE( a_uiBufferLen <= ULONG_MAX ); + bResult = InternetReadFile( + hHttpRequest, + &a_pBuffer[uiTotalBytesRead], + static_cast(a_uiBufferLen - uiTotalBytesRead), + &dwBytesRead ); + Trace("InternetReadFile", &a_pBuffer[uiTotalBytesRead], dwBytesRead); + if ( bResult ) + { + uiTotalBytesRead += dwBytesRead; + if ( dwBytesRead == 0 ) + { + if (pData->pRespHeaders) + { + free(pData->pRespHeaders); + pData->pRespHeaders = 0; + } + pData->bDisconnect = TRUE; + } + } + else + { + soap->error = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: frecv, error %d (%s) in InternetReadFile\n", + soap, soap->error, wininet_error_message(soap,soap->error) )); + soap_set_sender_error(soap, "InternetReadFile failed", wininet_error_message(soap,soap->error), SOAP_HTTP_ERROR); + } + } + while ( bResult && dwBytesRead && uiTotalBytesRead < a_uiBufferLen ); + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: recv, received %lu bytes\n", soap, uiTotalBytesRead )); + + return uiTotalBytesRead; +} + +/* gsoap documentation: + Called by client proxy multiple times, to close a socket connection before + a new socket connection is established and at the end of communications + when the SOAP_IO_KEEPALIVE flag is not set and soap.keep_alive = 0 + (indicating that the other party supports keep alive). Should return + SOAP_OK, or a gSOAP error code. Built-in gSOAP function: tcp_disconnect + */ +static int +wininet_disconnect( + struct soap * soap ) +{ + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + soap->error = SOAP_OK; + + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "wininet %p: disconnect\n", soap )); + + /* force a disconnect by setting the disconnect flag to TRUE */ + pData->bDisconnect = TRUE; + pData->bKeepAlive = FALSE; + wininet_have_connection( soap, pData ); + + return SOAP_OK; +} + +/* this is mostly for debug tracing */ +void CALLBACK +wininet_callback( + HINTERNET hInternet, + DWORD_PTR dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength ) +{ + struct soap * soap = (struct soap *) dwContext; + + UNUSED_ARG( hInternet ); + UNUSED_ARG( lpvStatusInformation ); + UNUSED_ARG( dwStatusInformationLength ); + + switch ( dwInternetStatus ) + { + case INTERNET_STATUS_RESOLVING_NAME: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_RESOLVING_NAME\n", soap )); + break; + case INTERNET_STATUS_NAME_RESOLVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_NAME_RESOLVED\n", soap )); + break; + case INTERNET_STATUS_CONNECTING_TO_SERVER: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CONNECTING_TO_SERVER\n", soap)); + break; + case INTERNET_STATUS_CONNECTED_TO_SERVER: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CONNECTED_TO_SERVER\n", soap)); + break; + case INTERNET_STATUS_SENDING_REQUEST: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_SENDING_REQUEST\n", soap)); + break; + case INTERNET_STATUS_REQUEST_SENT: + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_REQUEST_SENT, bytes sent = %lu\n", + soap, *(DWORD *)lpvStatusInformation )); + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + if ( pData->pProgressCallback ) + { + pData->pProgressCallback( TRUE, *(DWORD *)lpvStatusInformation, pData->pProgressCallbackContext ); + } + } + break; + case INTERNET_STATUS_RECEIVING_RESPONSE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_RECEIVING_RESPONSE\n", soap)); + break; + case INTERNET_STATUS_RESPONSE_RECEIVED: + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_RESPONSE_RECEIVED, bytes received = %lu\n", + soap, *(DWORD *)lpvStatusInformation )); + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + if ( pData->pProgressCallback ) + { + pData->pProgressCallback( FALSE, *(DWORD *)lpvStatusInformation, pData->pProgressCallbackContext ); + } + } + break; + case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CTL_RESPONSE_RECEIVED\n", soap)); + break; + case INTERNET_STATUS_PREFETCH: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_PREFETCH\n", soap)); + break; + case INTERNET_STATUS_CLOSING_CONNECTION: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CLOSING_CONNECTION\n", soap)); + break; + case INTERNET_STATUS_CONNECTION_CLOSED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_CONNECTION_CLOSED\n", soap)); + { + /* the connection has been closed, so we close the handle here */ + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + if ( pData->hConnection ) + { + /* + we only mark this for disconnection otherwise we get + errors when reading the data from the handle. In every + function that we use the connection we will check first to + see if it has been disconnected. + */ + pData->bDisconnect = TRUE; + } + } + break; + case INTERNET_STATUS_HANDLE_CREATED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_HANDLE_CREATED\n", soap)); + break; + case INTERNET_STATUS_HANDLE_CLOSING: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_HANDLE_CLOSING\n", soap)); + break; +#ifdef INTERNET_STATUS_DETECTING_PROXY + case INTERNET_STATUS_DETECTING_PROXY: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_DETECTING_PROXY\n", soap)); + break; +#endif + case INTERNET_STATUS_REQUEST_COMPLETE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_REQUEST_COMPLETE\n", soap)); + break; + case INTERNET_STATUS_REDIRECT: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_REDIRECT, new url = %s\n", + soap, (char*) lpvStatusInformation )); + break; + case INTERNET_STATUS_INTERMEDIATE_RESPONSE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_INTERMEDIATE_RESPONSE\n", soap)); + break; +#ifdef INTERNET_STATUS_USER_INPUT_REQUIRED + case INTERNET_STATUS_USER_INPUT_REQUIRED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_USER_INPUT_REQUIRED\n", soap)); + break; +#endif + case INTERNET_STATUS_STATE_CHANGE: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_STATE_CHANGE\n", soap)); + break; +#ifdef INTERNET_STATUS_COOKIE_SENT + case INTERNET_STATUS_COOKIE_SENT: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_COOKIE_SENT\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_COOKIE_RECEIVED + case INTERNET_STATUS_COOKIE_RECEIVED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_COOKIE_RECEIVED\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_PRIVACY_IMPACTED + case INTERNET_STATUS_PRIVACY_IMPACTED: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_PRIVACY_IMPACTED\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_P3P_HEADER + case INTERNET_STATUS_P3P_HEADER: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_P3P_HEADER\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_P3P_POLICYREF + case INTERNET_STATUS_P3P_POLICYREF: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_P3P_POLICYREF\n", soap)); + break; +#endif +#ifdef INTERNET_STATUS_COOKIE_HISTORY + case INTERNET_STATUS_COOKIE_HISTORY: + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: INTERNET_STATUS_COOKIE_HISTORY\n", soap)); + break; +#endif + } +} + +/* + check to ensure that our connection hasn't been disconnected + and disconnect remaining handles if necessary. + */ +static BOOL +wininet_have_connection( + struct soap * soap, + struct wininet_data * a_pData ) +{ + /* close the http request if we don't have a connection */ + BOOL bCloseRequest = a_pData->bDisconnect || !a_pData->hConnection; + if ( bCloseRequest && soap->socket != SOAP_INVALID_SOCKET ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: closing request\n", soap)); + + Trace("InternetCloseHandle (closing request)", 0, 0); + InternetCloseHandle( (HINTERNET) soap->socket ); + soap->socket = SOAP_INVALID_SOCKET; + +#if 0 + if ( a_pData->bKeepAlive ) + { + DWORD dwFlags; + HINTERNET hHttpRequest = NULL; + dwFlags = a_pData->dwRequestFlags | INTERNET_FLAG_NO_CACHE_WRITE; + if ( soap->omode & SOAP_IO_KEEPALIVE ) + { + dwFlags |= INTERNET_FLAG_KEEP_CONNECTION; + a_pData->bKeepAlive = TRUE; + } + /*if ( urlComponents.nScheme == INTERNET_SCHEME_HTTPS ) + { + dwFlags |= INTERNET_FLAG_SECURE; + }*/ + + hHttpRequest = HttpOpenRequestA( + a_pData->hConnection, "POST", "/MyWebService/Service.asmx"/*szUrlPath*/, "HTTP/1.1", NULL, NULL, + dwFlags, (DWORD_PTR) soap ); + if ( hHttpRequest ) + soap->socket = (SOAP_SOCKET) hHttpRequest; + else + a_pData->bKeepAlive = FALSE; + } +#endif + } + + /* close the connection if we don't have a request */ + if ( soap->socket == SOAP_INVALID_SOCKET && a_pData->hConnection && !a_pData->bKeepAlive ) + { + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: closing connection\n", soap)); + + Trace("InternetCloseHandle (closing connection)", 0, 0); + InternetCloseHandle( a_pData->hConnection ); + a_pData->hConnection = NULL; + } + a_pData->bDisconnect = FALSE; + + /* clean up the send details if we don't have a request */ + if ( soap->socket == SOAP_INVALID_SOCKET ) + { + if ( a_pData->pBuffer ) + { + free( a_pData->pBuffer ); + a_pData->pBuffer = 0; + } + a_pData->uiBufferLen = 0; + a_pData->uiBufferLenMax = INVALID_BUFFER_LENGTH; + } + + return (soap->socket != SOAP_INVALID_SOCKET); +} + +static int +wininet_fpoll( + struct soap * soap) +{ + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + return wininet_have_connection(soap, pData) ? SOAP_OK : SOAP_EOF; +} + + +static DWORD +wininet_set_timeout( + struct soap * soap, + struct wininet_data * a_pData, + const char * a_pszTimeout, + DWORD a_dwOption, + int a_nTimeout ) +{ + UNUSED_ARG( soap ); + UNUSED_ARG( a_pszTimeout ); + + if ( a_nTimeout > 0 ) + { + DWORD dwTimeout = a_nTimeout * 1000; + if ( !InternetSetOption( a_pData->hInternet, + a_dwOption, &dwTimeout, sizeof(DWORD) ) ) + { + DWORD dwErrorCode = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: failed to set %s timeout, error %d (%s)\n", + soap, a_pszTimeout, dwErrorCode, + wininet_error_message(soap,dwErrorCode) )); + return dwErrorCode; + } + } + return 0; +} + +/* +static BOOL +wininet_flag_set_option( + HINTERNET a_hHttpRequest, + DWORD a_dwOption, + DWORD a_dwFlag ) +{ + DWORD dwBuffer; + DWORD dwBufferLength = sizeof(DWORD); + + BOOL bSuccess = InternetQueryOption( + a_hHttpRequest, + a_dwOption, + &dwBuffer, + &dwBufferLength ); + if (bSuccess) { + dwBuffer |= a_dwFlag; + bSuccess = InternetSetOption( + a_hHttpRequest, + a_dwOption, + &dwBuffer, + dwBufferLength); + } +#ifdef SOAP_DEBUG + if ( !bSuccess ) { + DWORD dwErrorCode = GetLastError(); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, + "wininet %p: failed to set option: %X, error %d (%s)\n", + a_hHttpRequest, a_dwOption, dwErrorCode, + wininet_error_message(soap,dwErrorCode) )); + } +#endif + return bSuccess; +} +*/ + +static BOOL +wininet_resolve_send_error( + HINTERNET a_hHttpRequest, + DWORD a_dwErrorCode ) +{ + DWORD dwResult = InternetErrorDlg( + GetDesktopWindow(), + a_hHttpRequest, + a_dwErrorCode, + FLAGS_ERROR_UI_FILTER_FOR_ERRORS | + FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | + FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, + NULL ); + BOOL bRetVal = (a_dwErrorCode == ERROR_INTERNET_INCORRECT_PASSWORD) ? + (dwResult == ERROR_INTERNET_FORCE_RETRY) : + (dwResult == ERROR_SUCCESS); + /* If appropriate for your application, it is possible to ignore + errors in future once they have been handled or ignored once. + For example, to ignore invalid SSL certificate dates on this + connection once the client has indicated to ignore them this + time, uncomment this code. + */ + /* + if (bRetVal) + { + switch (a_dwErrorCode) + { + case ERROR_INTERNET_SEC_CERT_CN_INVALID: + wininet_flag_set_option(a_hHttpRequest, + INTERNET_OPTION_SECURITY_FLAGS, + SECURITY_FLAG_IGNORE_CERT_CN_INVALID ); + break; + } + } + */ + return bRetVal; + +} + +static const char * +wininet_error_message( + struct soap * soap, + DWORD a_dwErrorMsgId ) +{ + HINSTANCE hModule; + DWORD dwResult; + DWORD dwFormatFlags; + struct wininet_data * pData = + (struct wininet_data *) soap_lookup_plugin( soap, wininet_id ); + + /* free any existing error message */ + wininet_free_error_message( pData ); + + dwFormatFlags = + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM; + + /* load wininet.dll for the error messages */ + hModule = LoadLibraryExA( "wininet.dll", NULL, + LOAD_LIBRARY_AS_DATAFILE | DONT_RESOLVE_DLL_REFERENCES ); + if ( hModule ) + { + dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE; + } + + /* format the messages */ + wchar_t* pszErrorMessage = NULL; + dwResult = FormatMessageW( + dwFormatFlags, + hModule, + a_dwErrorMsgId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &pszErrorMessage, + 0, + NULL ); + + /* remove the CR LF from the error message and convert to proper char set */ + if ( dwResult > 2 ) + { + pszErrorMessage[dwResult-2] = 0; + + UINT newCodePage = CP_UTF8; // TODO: May be it should use SOAP_C_UTFSTRING or SOAP_C_MBSTRING? + int len = WideCharToMultiByte(newCodePage, 0, pszErrorMessage, -1, NULL, 0, NULL, NULL); + if (len) + { + pData->pszErrorMessage = new char[len]; + WideCharToMultiByte(newCodePage, 0, pszErrorMessage, -1, pData->pszErrorMessage, len, NULL, NULL); + } + else + { + pData->pszErrorMessage = NULL; + } + LocalFree( pszErrorMessage ); + } + else + { + pData->pszErrorMessage = NULL; + } + + /* free the library if we loaded it */ + if ( hModule ) + { + FreeLibrary( hModule ); + } + + if ( pData->pszErrorMessage ) + { + return pData->pszErrorMessage; + } + else + { + const static char szUnknown[] = "(unknown)"; + return szUnknown; + } +} + +static void +wininet_free_error_message( + struct wininet_data * a_pData ) +{ + if ( a_pData->pszErrorMessage ) + { + delete[] a_pData->pszErrorMessage; + a_pData->pszErrorMessage = 0; + } +} \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.h b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.h new file mode 100644 index 000000000..8e7ac60b0 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/gsoapWinInet.h @@ -0,0 +1,200 @@ +/* +=============================================================================== +GSOAP WININET PLUGIN +------------------------------------------------------------------------------- + +Allow gsoap clients (not servers) to direct all communications through the +WinInet API. This automatically provides all of the proxy and authentication +features supported by the control panel 'Internet Options' dialog to the +client. As these options are shared by IE, this means that "if IE works, +gsoap works." + +Project Home: http://code.google.com/p/gsoapwininet/ + +------------------------------------------------------------------------------- +Features +------------------------------------------------------------------------------- + + + gsoap plugin - extremely easy to use + + complete support for: + - HTTP/1.0 and HTTP/1.1 + - HTTPS (no extra libraries are required) + - HTTP authentication + - Proxy servers (simple, automatic discovery, etc) + - Proxy authentication (basic, NTLM, etc) + + authentication prompts and HTTPS warnings (e.g. invalid HTTPS CA) + can be resolved by the user via standard system dialog boxes. + + message size is limited only by available memory + + connect, receive and send timeouts are used + + supports all SOAP_IO types (see limitations) + + written completely in C, can be used in C, C++, and MFC projects + without modification (anywhere that gsoap is used) + + can be used in both MBCS and UNICODE projects + + compiles cleanly at warning level 4 (if gsoap uses SOAP_SOCKET + for the definition of sockets instead of int, it will also + compile without win64 warnings). + + all debug trace goes to the gsoap TEST.log file + + supports multiple threads (all plugin data is stored in the + soap structure - no static variables) + +------------------------------------------------------------------------------- +Limitations +------------------------------------------------------------------------------- + - DIME attachments are not supported + - may internally buffer the entire outgoing message before sending + (if the serialized message is larger then SOAP_BUFLEN, or if + SOAP_IO_CHUNK mode is being used then the entire message will + be buffered) + +------------------------------------------------------------------------------- +Usage +------------------------------------------------------------------------------- + +Add the gsoapWinInet2.h and gsoapWinInet2.cpp files to your project (if you +have a C project, rename gsoapWinInet2.cpp to .c and use it as is). Ensure +that you turn off precompiled headers for the .cpp file. + +In your source, just after calling soap_init(), register this plugin with +soap_register_plugin( soap, wininet_plugin ). + +For example: + struct soap soap; + soap_init( &soap ); + soap_register_plugin( &soap, wininet_plugin ); + soap.connect_timeout = 5; // this will be used by wininet too + ... + soap_done(&soap); + +------------------------------------------------------------------------------- +Notes +------------------------------------------------------------------------------- + +For extra control, you may also register this plugin using the +soap_register_plugin_arg() function, and supply as the argument flags which +you want to be passed to HttpOpenRequest. + +For example: + struct soap soap; + soap_init( &soap ); + soap_register_plugin_arg( &soap, wininet_plugin, + (void*) INTERNET_FLAG_IGNORE_CERT_CN_INVALID ); + +See the MSDN documentation on HttpOpenRequest for details of available flags. +The header file is required for the definitions of the flags. +Some flags which may be useful are: + +INTERNET_FLAG_KEEP_CONNECTION + + Uses keep-alive semantics, if available, for the connection. + This flag is required for Microsoft Network (MSN), NT LAN + Manager (NTLM), and other types of authentication. + ++ Note that this flag is used automatically when soap.omode + has the SOAP_IO_KEEPALIVE flag set. ++ + +INTERNET_FLAG_IGNORE_CERT_CN_INVALID + + Disables Microsoft Win32 Internet function checking of SSL/PCT- + based certificates that are returned from the server against + the host name given in the request. + +INTERNET_FLAG_IGNORE_CERT_DATE_INVALID + + Disables Win32 Internet function checking of SSL/PCT-based + certificates for proper validity dates. + +This plugin uses the following callback functions and is not compatible +with any other plugin that uses these functions. + + soap->fopen + soap->fposthdr + soap->fsend + soap->frecv + soap->fclose + +If there are errors in sending the HTTP request which would cause a dialog +box to be displayed in IE (for instance, invalid certificates on an HTTPS +connection), then a dialog will also be displayed by this library. At the +moment is is not possible to disable the UI. If you wish to remove the UI +then you will need to hack the source to remove the dialog box and resolve the +errors programmatically, or supply the appropriate flags in +soap_register_plugin_arg() to disable the unwanted warnings. + +Because messages are buffered internally to gsoapWinInet2 plugin it is +recommended that the SOAP_IO_STORE flag is not used otherwise the message may +be buffered twice on every send. Use the default flag SOAP_IO_BUFFER, +or SOAP_IO_FLUSH. + +------------------------------------------------------------------------------- +License +------------------------------------------------------------------------------- + +The licence text below is the boilerplate "MIT Licence" used from: +http://www.opensource.org/licenses/mit-license.php + +Copyright (c) 2009, Brodie Thiesfield + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------------------------------------------------------------------------------- +Developers +------------------------------------------------------------------------------- + +26 May 2003: Jack Kustanowitz (jackk@atomica.com) +Original version + +29 September 2003: Brodie Thiesfield (code@jellycan.com) +Rewritten as C plugin for gsoap. Bugs fixed and features added. + +14 January 2004: Brodie Thiesfield (code@jellycan.com) +Bug fix. + +17 March 2009: Brodie Thiesfield (code@jellycan.com) +Clean up and re-release. +*/ + +#ifndef INCLUDED_gsoapWinInet2_h +#define INCLUDED_gsoapWinInet2_h + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + rseFalse = 0, + rseTrue, + rseDisplayDlg +} wininet_rseReturn; + +typedef wininet_rseReturn(*wininet_rse_callback)(HINTERNET a_hHttpRequest, DWORD a_dwErrorCode); + +extern void wininet_set_rse_callback(struct soap *a_pSoap, wininet_rse_callback a_pRseCallback); + +typedef void (*wininet_progress_callback)(BOOL a_bSend, SIZE_T a_dwBytesCount, LPVOID pContext); + +extern void wininet_set_progress_callback(struct soap *a_pSoap, wininet_progress_callback a_pProgressCallback, LPVOID a_pContext); + +extern int wininet_plugin(struct soap *a_pSoap, struct soap_plugin *a_pPluginData, void *a_pUnused); + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDED_gsoapWinInet2_h diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/make_service_stub.bat b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/make_service_stub.bat new file mode 100644 index 000000000..d3a11b020 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/make_service_stub.bat @@ -0,0 +1,12 @@ +SET DumpUploaderHeader=DumpUploader.h +SET DumpUploaderUrl=https://www.crash-server.com/crashserver/DumpUploader.asmx?WSDL +rem SET DumpUploaderUrl=http://localhost:59175/DumpUploader.asmx?WSDL +SET DumpUploaderPath=%~dp0\generated +SET GsoapPath=%~dp0\..\..\external\gsoap-win32-2.8.0 +SET TypemapDatPath=%~dp0\typemap.dat + +if not exist "%DumpUploaderPath%" md "%DumpUploaderPath%" +cd "%DumpUploaderPath%" + +"%GsoapPath%\bin\win32\wsdl2h.exe" -t "%TypemapDatPath%" -o "%DumpUploaderHeader%" "%DumpUploaderUrl%" +"%GsoapPath%\bin\win32\soapcpp2.exe" -2 -i -C -x "%DumpUploaderHeader%" "-I%GsoapPath%\import" diff --git a/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/typemap.dat b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/typemap.dat new file mode 100644 index 000000000..e717b3704 --- /dev/null +++ b/ext/CrashServer/CrashHandler/DumpUploaderServiceLib/typemap.dat @@ -0,0 +1,210 @@ +# typemap.dat +# +# Use this file to define namespace prefix and type bindings for +# the generated header files by the 'wsdl2h' tool. typemap.dat is the +# default file processed by 'wsdl2h' to customize its output. You can use +# wsdl2h option -t to specify an alternate file. +# +# XML namespace prefix bindings can be provided to override the default +# choice of the ns1, ns2, ... prefixes generated by wsdl2h. It is highly +# recommended to provide namespace prefixes for your project's XML +# namespaces. In this way, changes to the WSDL (or newer releases of +# wsdl2h) will have a minimal impact on coding. +# Bindings for namespace prefixes are of the form: +# prefix = "URI" +# +# Type bindings can by provided to bind XML schema types to C/C++ types +# for your project. +# Type bindings are of the form: +# prefix__type = declaration | use | ptr-use +# where 'declaration' introduces the type in the header file, 'use' +# specifies how the type is used directly, 'ptr-use' specifies how the +# type is used as a pointer type. +# For example: +# xsd__string = | char* | char* +# After enabling this line, all XSD strings will be mapped to char*. Note +# that the 'declaration' part is empty in this case. +# +# Member data and functions can be provided to extend a generated struct +# or class. +# Class and struct extensions are of the form: +# prefix__type = $ member-declaration +# For example, to add a constructor and destructor to class myns__record: +# myns__record = $ myns__record(); +# myns__record = $ ~myns__record(); +# +# Any other material to be included in the generated header file can be +# provided by enclosing the text within brackets [ and ]. Brackets MUST +# appear at the start of a new line. +# For example, to include a note: +#[ +#// TODO: Don't forget to bind the namespace prefixes! +#] +# This comment appears as the first line in the generated header file. +# +#------------------------------------------------------------------------------- +#gSOAP XML Web services tools +#Copyright (C) 2004-2005, Robert van Engelen, Genivia Inc. All Rights Reserved. +#This software is released under one of the following two licenses: +#GPL or Genivia's license for commercial use. +#------------------------------------------------------------------------------- +#GPL license. +# +#This program is free software; you can redistribute it and/or modify it under +#the terms of the GNU General Public License as published by the Free Software +#Foundation; either version 2 of the License, or (at your option) any later +#version. +# +#This program is distributed in the hope that it will be useful, but WITHOUT ANY +#WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +#PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License along with +#this program; if not, write to the Free Software Foundation, Inc., 59 Temple +#Place, Suite 330, Boston, MA 02111-1307 USA +# +#Author contact information: +#engelen@genivia.com / engelen@acm.org +#------------------------------------------------------------------------------- +#A commercial use license is available from Genivia, Inc., contact@genivia.com +#------------------------------------------------------------------------------- + +[ +// Reminder: Modify typemap.dat to customize the header file generated by wsdl2h +] + +# To use struct tm instead of time_t for xsd:dateTime: +# +# xsd__dateTime = #import "custom/struct_tm.h" | xsd__dateTime + +# To use struct timeval with usec precision xsd:dateTime: +# +# xsd__dateTime = #import "custom/struct_timeval.h" | xsd__dateTime + +# For WhiteMesa interoperability testing round 2: + +i = "http://soapinterop.org/" +s = "http://soapinterop.org/xsd" + +# Amazon Web Services: + +aws = "urn:PI/DevCentral/SoapService" + +# Mappoint Web services: + +mpt = "http://s.mappoint.net/mappoint-30/" + +# MTOM xop and xmime are imported from xop.h, xmime.h, and xmlmime.h: +# Note: changed xmlmime to xmime to avoid other MTOM tools from +# complaining that 'xml' is reserved. + +xop = +xmime = +xmime4 = +xmime5 = + +# xop:Include is imported from xop.h and redefined as _xop__Include: + +xop__Include = #import "xop.h" | _xop__Include + +# xmime/xmlmime:contentType attribute is a string: + +_xmime__contentType = | char* | char* +_xmime4__contentType = | char* | char* +_xmime5__contentType = | char* | char* + +# WS-Addressing (2003, 2004, and 2005 schemas) +# See import/wsa.h, import/wsa3.h etc for definitions and code examples +# The API is defined in plugin/wsaapi.c, plugin/wsaapi3.c, etc. + +wsa = +wsa3 = +wsa4 = +wsa5 = + +# The types below should not use pointers, so we add a 3rd column: + +_wsa__Action = | | _wsa__Action +_wsa__MessageID = | | _wsa__MessageID +_wsa__To = | | _wsa__To + +_wsa3__Action = | | _wsa3__Action +_wsa3__MessageID = | | _wsa3__MessageID +_wsa3__To = | | _wsa3__To + +_wsa4__Action = | | _wsa4__Action +_wsa4__MessageID = | | _wsa4__MessageID +_wsa4__To = | | _wsa4__To + +_wsa5__Action = | | _wsa5__Action +_wsa5__MessageID = | | _wsa5__MessageID +_wsa5__To = | | _wsa5__To + +# WS-ReliableMessaging (WS-Reliability 2004) + +wsrm = +wsrm4 = + +# WS-Policy + +wsp = + +# WS-Security wsse 2004 and old wsse 2002 schema + +wsse = +wsse2 = + +# wsu 2004 + +wsu = + +_wsu__Id = | char* +_wsu__Created = | time_t +_wsu__Expires = | time_t + +wsu__AttributedDateTime = | time_t +wsu__AttributedURI = | char* + +# Bindings for ds and xenc for WS-Security protocols: + +ds = +xenc = + +# xlink + +xlink = + +_xlink__actuate = | char* +_xlink__arcrole = | char* +_xlink__from = | char* +_xlink__href = | char* +_xlink__label = | char* +_xlink__role = | char* +_xlink__show = | char* +_xlink__to = | char* +_xlink__title = | char* +_xlink__type = | char* + +# wsrp routing protocol (deprecated) + +wsrp = + +# Remember: type bindings are given on a single line (use \ when needed). +# Here is an example binding for the XSD int type: + +# xsd__int = | int + +# To use regular char* strings instead of std::string, use: + +xsd__string = | std::wstring | std::wstring* + +# For char* serialized with xsi:type when using soapcpp2 option -t, use: + +# xsd__string = typedef char *xsd__string; | xsd__string | xsd__string + +# More examples: + +# xsd__boolean = enum xsd__boolean { false_, true_ }; | enum xsd__boolean + +# xsd__base64Binary = class xsd__base64Binary { unsigned char *__ptr; int __size; }; | xsd__base64Binary | xsd__base64Binary +xsd__base64Binary = #import "xop.h" | _xop__Include diff --git a/ext/CrashServer/CrashHandler/SendRpt/Config.h b/ext/CrashServer/CrashHandler/SendRpt/Config.h new file mode 100644 index 000000000..69009554d --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/Config.h @@ -0,0 +1,48 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include + +struct Config +{ + CStringA Prefix; + CStringW AppName; + CStringW Company; + CStringW PrivacyPolicyUrl; + USHORT V[4]; + USHORT Hotfix; + CStringW ApplicationGUID; + BOOL ServiceMode; // Service is terminated after all dumps has been collected, then send all needed information. + BOOL LeaveDumpFilesInTempFolder; + BOOL OpenProblemInBrowser; + BOOL UseWER; + DWORD SubmitterID; + CStringW ProcessName; + std::vector > FilesToAttach; + std::vector > UserInfo; +}; + +struct Params +{ + HANDLE Process; + DWORD ProcessId; + MINIDUMP_EXCEPTION_INFORMATION ExceptInfo; + BOOL WasAssert; + HANDLE ReportReady; +}; diff --git a/ext/CrashServer/CrashHandler/SendRpt/CrashInfo.cpp b/ext/CrashServer/CrashHandler/SendRpt/CrashInfo.cpp new file mode 100644 index 000000000..c6965d887 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/CrashInfo.cpp @@ -0,0 +1,85 @@ +#include "StdAfx.h" +#define PSAPI_VERSION 1 +#include +#include "CrashInfo.h" + +#pragma comment(lib, "Psapi.lib") + +DWORD _GetProcessHandleCount(HANDLE hProcess) +{ + DWORD handleCount = 0; + HMODULE hKernel32 = GetModuleHandle(_T("kernel32.dll")); + if (hKernel32 != NULL) + { + typedef BOOL (WINAPI *LPGETPROCESSHANDLECOUNT)(HANDLE, PDWORD); + LPGETPROCESSHANDLECOUNT pfnGetProcessHandleCount = + (LPGETPROCESSHANDLECOUNT) GetProcAddress(hKernel32, "GetProcessHandleCount"); + if (pfnGetProcessHandleCount != NULL) + pfnGetProcessHandleCount(hProcess, &handleCount); + } + return handleCount; +} + +CString GetGeoLocation() +{ + CString res; + + GEOID geoLocation = GetUserGeoID(GEOCLASS_NATION); + if (geoLocation != GEOID_NOT_AVAILABLE) + { + TCHAR geoInfo[1024] = _T(""); + int n = GetGeoInfo(geoLocation, GEO_RFC1766, geoInfo, _countof(geoInfo), 0); + if (n != 0) + res = geoInfo; + } + + return res; +} + +CrashInfo::CrashInfo(HANDLE hProcess) +{ + if (hProcess == NULL) + return; + + m_guiResources = GetGuiResources(hProcess, GR_GDIOBJECTS); + m_processHandleCount = _GetProcessHandleCount(hProcess); + + PROCESS_MEMORY_COUNTERS meminfo = {}; + GetProcessMemoryInfo(hProcess, &meminfo, sizeof(meminfo)); + m_workingSetSize = meminfo.WorkingSetSize; + m_privateMemSize = meminfo.PagefileUsage; + + MEMORYSTATUSEX memstat = {}; + memstat.dwLength = sizeof(memstat); + GlobalMemoryStatusEx(&memstat); + m_physicalSize = memstat.ullTotalPhys; + m_physicalFreeSize = memstat.ullAvailPhys; + + m_geoLocation = GetGeoLocation(); +} + +bool CrashInfo::GetCrashInfoFile(const CString& crashInfoFile) const +{ + FILE* f = NULL; + if (0 != _tfopen_s(&f, crashInfoFile, _T("wt"))) + return false; + fprintf_s(f, + "\n" + " %ls\n" + " %d\n" + " %d\n" + " %I64u\n" + " %I64u\n" + " %I64u\n" + " %I64u\n" + "", + (LPCWSTR)m_geoLocation, + m_guiResources, + m_processHandleCount, + m_workingSetSize / 1024, + m_privateMemSize / 1024, + m_physicalSize / (1024 * 1024), + m_physicalFreeSize / (1024 * 1024)); + fclose(f); + return true; +} \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/CrashInfo.h b/ext/CrashServer/CrashHandler/SendRpt/CrashInfo.h new file mode 100644 index 000000000..86769cd2e --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/CrashInfo.h @@ -0,0 +1,17 @@ +#pragma once + +class CrashInfo +{ +public: + CrashInfo(HANDLE hProcess); + bool GetCrashInfoFile(const CString& crashInfoFile) const; + +private: + DWORD m_guiResources; + DWORD m_processHandleCount; + ULONGLONG m_workingSetSize; + ULONGLONG m_privateMemSize; + ULONGLONG m_physicalSize; + ULONGLONG m_physicalFreeSize; + CString m_geoLocation; +}; \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/CrashProcessor.cpp b/ext/CrashServer/CrashHandler/SendRpt/CrashProcessor.cpp new file mode 100644 index 000000000..047369f08 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/CrashProcessor.cpp @@ -0,0 +1,981 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "stdafx.h" +#include "Serializer.h" +#include "DumpWriter.h" +#include "..\..\CommonLibs\Zlib\ZipUnzip.h" +#include "..\..\CommonLibs\Log\log.h" +#include "..\..\CommonLibs\Log\log_media.h" +#include "SendReportDlg.h" +#include "..\DumpUploaderServiceLib\DumpUploaderWebService.h" +#include "..\CrashHandler\CrashHandler.h" +#include "CrashInfo.h" + +Config g_Config; +Log g_Log(NULL, _T("sendrpt")); + +using namespace std; + +BOOL IsWow64() +{ + typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + LPFN_ISWOW64PROCESS fnIsWow64Process = NULL; + + BOOL bIsWow64 = FALSE; + + HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); + if (NULL != hKernel32) + fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hKernel32,"IsWow64Process"); + + if (NULL != fnIsWow64Process) + fnIsWow64Process(GetCurrentProcess(), &bIsWow64); + + return bIsWow64; +} + +struct ModuleInfo +{ + CStringW name; + USHORT V[4]; +}; + +class DumpFilter +{ +public: + DumpFilter(vector& _Modules, DWORD _SaveOnlyThisThreadID = 0) + : Modules(_Modules), SaveOnlyThisThreadID(_SaveOnlyThisThreadID) + { + Callback.CallbackRoutine = _MinidumpCallback; + Callback.CallbackParam = this; + } + + operator MINIDUMP_CALLBACK_INFORMATION*() { return &Callback; } + +private: + MINIDUMP_CALLBACK_INFORMATION Callback; + DWORD SaveOnlyThisThreadID; + vector& Modules; + + BOOL MinidumpCallback( + const PMINIDUMP_CALLBACK_INPUT CallbackInput, + PMINIDUMP_CALLBACK_OUTPUT CallbackOutput) + { + switch (CallbackInput->CallbackType) + { + case IncludeThreadCallback: + if (SaveOnlyThisThreadID != 0 && CallbackInput->IncludeThread.ThreadId != SaveOnlyThisThreadID) + return FALSE; + break; + case ThreadCallback: + if (SaveOnlyThisThreadID != 0 && CallbackInput->Thread.ThreadId != SaveOnlyThisThreadID) + CallbackOutput->ThreadWriteFlags = 0; + break; + case ModuleCallback: + { + ModuleInfo mi; + WCHAR drive[MAX_PATH], dir[MAX_PATH], fname[MAX_PATH], ext[MAX_PATH]; + _wsplitpath_s(CallbackInput->Module.FullPath, drive, dir, fname, ext); + mi.name = CStringW(fname) + ext; + mi.name.MakeLower(); + mi.V[0] = HIWORD(CallbackInput->Module.VersionInfo.dwProductVersionMS); + mi.V[1] = LOWORD(CallbackInput->Module.VersionInfo.dwProductVersionMS); + mi.V[2] = HIWORD(CallbackInput->Module.VersionInfo.dwProductVersionLS); + mi.V[3] = LOWORD(CallbackInput->Module.VersionInfo.dwProductVersionLS); + Modules.push_back(mi); + } + break; + } + + return TRUE; + } + + static BOOL CALLBACK _MinidumpCallback( + PVOID CallbackParam, + const PMINIDUMP_CALLBACK_INPUT CallbackInput, + PMINIDUMP_CALLBACK_OUTPUT CallbackOutput) + { + return static_cast(CallbackParam)->MinidumpCallback(CallbackInput, CallbackOutput); + } +}; + +struct Solution +{ + bool askConfirmation; + ns1__SolutionType type; + wstring url; + vector exe; +}; + +struct Response +{ + ns1__ResponseType type; + wstring error; + auto_ptr solution; + std::wstring clientID; + int problemID; + int dumpGroupID; + int dumpID; + std::wstring urlToProblem; + ns1__AdditionalInfoType infoType; + vector infoModule; + std::wstring infoModuleCfg; + + void Fill(const ns1__Response& response) + { + type = response.type; + g_Log.Debug(_T("There is response type = %d:"), type); + if (response.error) + { + error = *response.error; + g_Log.Debug(_T("\terror\t\"%ls\""), error.c_str()); + } + if (response.solution) + { + g_Log.Debug(_T("\thas solution")); + solution.reset(new Solution); + solution->askConfirmation = response.solution->askConfirmation; + solution->type = response.solution->type; + g_Log.Debug(_T("\t\ttype\t%d"), solution->type); + if (response.solution->url) + { + solution->url = *response.solution->url; + g_Log.Debug(_T("\t\tURL\t%ls"), solution->url.c_str()); + } + if (response.solution->exe) + { + solution->exe.assign(response.solution->exe->__ptr, response.solution->exe->__ptr + response.solution->exe->__size); + g_Log.Debug(_T("\t\thas EXE, size\t%d"), solution->exe.size()); + } + } + if (response.clientID) + { + clientID = *response.clientID; + g_Log.Debug(_T("\tCliendID = \"%ls\""), clientID.c_str()); + } + problemID = response.problemID; + dumpGroupID = response.dumpGroupID; + dumpID = response.dumpID; + g_Log.Debug(_T("\tproblemID = %d, dumpGroupID = %d, dumpID = %d"), problemID, dumpGroupID, dumpID); + if (response.urlToProblem) + { + urlToProblem = *response.urlToProblem; + g_Log.Debug(_T("\tURL to problem = \"%ls\""), urlToProblem.c_str()); + } + else + { + urlToProblem.clear(); + } + infoType = response.infoType; + if (response.infoModule && response.infoModule->__size > 0) + infoModule.assign(response.infoModule->__ptr, response.infoModule->__ptr + response.infoModule->__size); + else + infoModule.clear(); + if (response.infoModuleCfg) + infoModuleCfg = *response.infoModuleCfg; + else + infoModuleCfg.clear(); + } +}; + +class CrashProcessor +{ + auto_ptr m_CrashInfo; + CString m_TempFolder; + CString m_MiniDumpFile; + CString m_MiniDumpZipFile; + CString m_FullDumpFile; + CString m_FullDumpZipFile; + CString m_InfoDll; + CString m_InfoFile; + CString m_Patch; + DumpWriter m_DumpWriter; + DumpUploaderWebService m_WebService; + CWindow* volatile m_pProgressDlg; + bool m_bStop; + +public: + CrashProcessor() + : m_bStop(false) + , m_pProgressDlg(NULL) + , m_WebService(5*60 /* Parsing a dump may require a lot of time (for example if symbols are uploaded from microsoft) */) + { + } + + ~CrashProcessor() + { + if (!m_FullDumpFile.IsEmpty()) + DeleteFile(m_FullDumpFile); + if (!m_MiniDumpFile.IsEmpty()) + DeleteFile(m_MiniDumpFile); + if (!g_Config.LeaveDumpFilesInTempFolder) + { + if (!m_FullDumpZipFile.IsEmpty()) + DeleteFile(m_FullDumpZipFile); + if (!m_MiniDumpZipFile.IsEmpty()) + DeleteFile(m_MiniDumpZipFile); + if (!m_TempFolder.IsEmpty()) + RemoveDirectory(m_TempFolder); + } + } + + void InitPathes() + { + GetTempPath(MAX_PATH, m_TempFolder.GetBuffer(MAX_PATH)); + m_TempFolder.ReleaseBuffer(); + + SYSTEMTIME st; + GetLocalTime(&st); + + CString t; + t.Format(_T("%s_%d.%d.%d.%d_%04d%02d%02d_%02d%02d%02d"), + (LPCTSTR)CA2CT(g_Config.Prefix), + g_Config.V[0], g_Config.V[1], g_Config.V[2], g_Config.V[3], + (int)st.wYear, (int)st.wMonth, (int)st.wDay, (int)st.wHour, (int)st.wMinute, (int)st.wSecond); + + m_TempFolder += t; + m_MiniDumpFile = m_TempFolder + _T("\\") + t + _T(".mini.dmp"); + m_MiniDumpZipFile = m_TempFolder + _T("\\mini.zip"); + m_FullDumpFile = m_TempFolder + _T("\\") + t + _T(".full.dmp"); + m_FullDumpZipFile = m_TempFolder + _T("\\full.zip"); + m_InfoDll = m_TempFolder + _T("\\info.dll"); + m_InfoFile = m_TempFolder + _T("\\info.zip"); + m_Patch = m_TempFolder + _T("\\solution.exe"); + + if (!CreateDirectory(m_TempFolder, NULL)) + throw std::runtime_error("failed to create temp directory"); + } + + static void FillClientLib(ns1__ClientLib* client) + { + client->v1 = 0; + client->v2 = 0; + client->v3 = 0; + client->v4 = 0; + client->arch = +#ifdef _M_AMD64 + ns1__Architecture__x64 +#else + ns1__Architecture__x32 +#endif + ; + + TCHAR path[MAX_PATH]; + if (!GetModuleFileName(NULL, path, _countof(path))) + return; + + vector verInfo(GetFileVersionInfoSize(path, NULL)); + VS_FIXEDFILEINFO* lpFileinfo = NULL; + UINT uLen; + if (!GetFileVersionInfo(path, 0, static_cast(verInfo.size()), &verInfo[0]) + || !VerQueryValue(&verInfo[0], _T("\\"), (LPVOID*)&lpFileinfo, &uLen)) + return; + client->v1 = HIWORD(lpFileinfo->dwProductVersionMS); + client->v2 = LOWORD(lpFileinfo->dwProductVersionMS); + client->v3 = HIWORD(lpFileinfo->dwProductVersionLS); + client->v4 = LOWORD(lpFileinfo->dwProductVersionLS); + g_Log.Info(_T("Client lib %d.%d.%d.%d"), client->v1, client->v2, client->v3, client->v4); + } + + static void FillApp(ns1__Application* app) + { + app->applicationGUID = g_Config.ApplicationGUID; + app->v1 = g_Config.V[0]; + app->v2 = g_Config.V[1]; + app->v3 = g_Config.V[2]; + app->v4 = g_Config.V[3]; + app->hotfix = g_Config.Hotfix; + g_Log.Info(_T("App %d.%d.%d.%d %ls"), app->v1, app->v2, app->v3, app->v4, app->applicationGUID.c_str()); + } + + static int GetUserGuid() + { + int nUserGuid = 12345; + HKEY hCryptography; +#if defined (_WIN64) + DWORD param = 0; +#else + DWORD param = IsWow64() ? KEY_WOW64_64KEY : 0; +#endif + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Cryptography"), 0, KEY_READ|param, &hCryptography)) + { + TCHAR guid[1024]; + DWORD size = sizeof(guid); + if (ERROR_SUCCESS == RegQueryValueEx(hCryptography, _T("MachineGuid"), NULL, NULL, (LPBYTE)guid, &size)) + { + DWORD D1 = 0, D2 = 0, D3 = 0, D4 = 0, D5 = 0, D6 = 0; + _stscanf_s(guid, _T("%08x-%04x-%04x-%04x-%04x%08x"), &D1, &D2, &D3, &D4, &D5, &D6); + DWORD DD1 = MAKELONG(D2, D3); + DWORD DD2 = MAKELONG(D4, D5); + nUserGuid = D1 ^ MAKELONG(D3, D2) ^ MAKELONG(D5, D4) ^ D6; + } + RegCloseKey(hCryptography); + } + g_Log.Info(_T("User ID 0x%08X"), nUserGuid); + return nUserGuid; + } + + Response Hello(const vector& modules) + { + g_Log.Info(_T("Sending Hello...")); + + Response result; + + wstring mainModule = g_Config.ProcessName; + + _ns1__Hello* pRequest = soap_new__ns1__Hello(&m_WebService, 1); + pRequest->client = soap_new_ns1__ClientLib(&m_WebService, 1); + pRequest->app = soap_new_ns1__Application(&m_WebService, 1); + pRequest->mainModule = &mainModule; + FillClientLib(pRequest->client); + FillApp(pRequest->app); + + _ns1__HelloResponse* pResponse = soap_new__ns1__HelloResponse(&m_WebService, 1); + + bool bReqOK = m_WebService.Hello(pRequest, pResponse) == SOAP_OK; + + if (bReqOK) + result.Fill(*pResponse->HelloResult); + + soap_delete__ns1__HelloResponse(&m_WebService, pResponse); + soap_delete_ns1__Application(&m_WebService, pRequest->app); + soap_delete_ns1__ClientLib(&m_WebService, pRequest->client); + soap_delete__ns1__Hello(&m_WebService, pRequest); + + if (!bReqOK) + throw runtime_error((const char*)CW2A(m_WebService.GetErrorText().c_str())); + + return result; + } + + Response UploadMiniDump(const CString& dumpFile) + { + g_Log.Info(_T("Sending UploadMiniDump...")); + + Response result; + + wstring mainModule = g_Config.ProcessName; + + vector data = ReadFile(dumpFile); + + _ns1__UploadMiniDump* pRequest = soap_new__ns1__UploadMiniDump(&m_WebService, 1); + pRequest->client = soap_new_ns1__ClientLib(&m_WebService, 1); + pRequest->app = soap_new_ns1__Application(&m_WebService, 1); + pRequest->mainModule = &mainModule; + FillClientLib(pRequest->client); + FillApp(pRequest->app); + pRequest->PCID = GetUserGuid(); + pRequest->submitterID = g_Config.SubmitterID; + pRequest->dump = soap_new__xop__Include(&m_WebService, 1); + pRequest->dump->__ptr = &data[0]; + pRequest->dump->__size = static_cast(data.size()); + pRequest->dump->id = NULL; + pRequest->dump->options = NULL; + pRequest->dump->type = "binary"; + + _ns1__UploadMiniDumpResponse* pResponse = soap_new__ns1__UploadMiniDumpResponse(&m_WebService, 1); + + bool bReqOK = m_WebService.UploadMiniDump(pRequest, pResponse) == SOAP_OK; + + if (bReqOK) + result.Fill(*pResponse->UploadMiniDumpResult); + + soap_delete__ns1__UploadMiniDumpResponse(&m_WebService, pResponse); + soap_delete__xop__Include(&m_WebService, pRequest->dump); + + soap_delete_ns1__Application(&m_WebService, pRequest->app); + soap_delete_ns1__ClientLib(&m_WebService, pRequest->client); + soap_delete__ns1__UploadMiniDump(&m_WebService, pRequest); + + if (!bReqOK) + throw runtime_error((const char*)CW2A(m_WebService.GetErrorText().c_str())); + + if (m_bStop) + throw std::runtime_error("canceled"); + + return result; + } + + Response SendAdditionalInfoUploadRejected(const int miniDumpId) + { + g_Log.Info(_T("Sending SendAdditionalInfoUploadRejected...")); + + return UploadAdditionalInfo(miniDumpId, NULL, ns1__AdditionalInfoType__None); + } + + Response UploadAdditionalInfo(const int miniDumpId, const CString& addInfoFile, const bool isFullDump) + { + g_Log.Info(_T("Sending UploadAdditionalInfo...")); + + vector data = ReadFile(addInfoFile); + + return UploadAdditionalInfo(miniDumpId, &data, isFullDump ? ns1__AdditionalInfoType__FullDump : ns1__AdditionalInfoType__Info); + } + + static vector ReadFile(const CString& path) + { + vector data; + CAtlFile file(CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); + if (file == INVALID_HANDLE_VALUE) + throw runtime_error(std::string("failed to open file ") + (const char*)CT2A(path)); + ULONGLONG fileSize; + if (FAILED(file.GetSize(fileSize))) + throw runtime_error(std::string("failed to get file size ") + (const char*)CT2A(path)); + + if (fileSize != 0) + { + data.resize((size_t)fileSize); + if (FAILED(file.Read(&data[0], static_cast(fileSize)))) + throw runtime_error(std::string("failed to read file ") + (const char*)CT2A(path)); + } + + return data; + } + + struct ProgressNotifier + { + size_t m_sent; + size_t m_total; + CrashProcessor& m_crashProcessor; + ProgressNotifier(size_t total, CrashProcessor& crashProcessor) : m_sent(0), m_total(total), m_crashProcessor(crashProcessor) {} + + static void ProgressCallback(BOOL send, SIZE_T bytesCount, LPVOID context) + { + static_cast(context)->ProgressCallback(send, bytesCount); + } + void ProgressCallback(BOOL send, SIZE_T bytesCount) + { + if (!send) + return; + m_sent += bytesCount; + if (m_sent > m_total) + m_sent = m_total; + + if (m_crashProcessor.m_pProgressDlg) + m_crashProcessor.m_pProgressDlg->PostMessage(WM_USER, m_total, m_sent); + } + }; + + Response UploadAdditionalInfo(const int miniDumpId, vector *data, const ns1__AdditionalInfoType infoType) + { + Response result; + + wstring mainModule = g_Config.ProcessName; + + _ns1__UploadAdditionalInfo* pRequest = soap_new__ns1__UploadAdditionalInfo(&m_WebService, 1); + pRequest->client = soap_new_ns1__ClientLib(&m_WebService, 1); + pRequest->app = soap_new_ns1__Application(&m_WebService, 1); + pRequest->mainModule = &mainModule; + FillClientLib(pRequest->client); + FillApp(pRequest->app); + pRequest->miniDumpID = miniDumpId; + pRequest->info = soap_new__xop__Include(&m_WebService, 1); + if (data && !data->empty()) + { + pRequest->info->__ptr = &(*data->begin()); + pRequest->info->__size = static_cast(data->size()); + } + else + { + pRequest->info->__ptr = NULL; + pRequest->info->__size = 0; + } + pRequest->info->id = NULL; + pRequest->info->options = NULL; + pRequest->info->type = "binary"; + pRequest->infoType = infoType; + + _ns1__UploadAdditionalInfoResponse* pResponse = soap_new__ns1__UploadAdditionalInfoResponse(&m_WebService, 1); + auto_ptr pProgress; + if (data) + { + pProgress.reset(new ProgressNotifier(data->size(), *this)); + m_WebService.SetProgressCallback(ProgressNotifier::ProgressCallback, pProgress.get()); + } + bool bReqOK = m_WebService.UploadAdditionalInfo(pRequest, pResponse) == SOAP_OK; + if (data) + m_WebService.SetProgressCallback(NULL, NULL); + + if (bReqOK) + result.Fill(*pResponse->UploadAdditionalInfoResult); + + soap_delete__ns1__UploadAdditionalInfoResponse(&m_WebService, pResponse); + if (data) + soap_delete__xop__Include(&m_WebService, pRequest->info); + soap_delete_ns1__Application(&m_WebService, pRequest->app); + soap_delete_ns1__ClientLib(&m_WebService, pRequest->client); + soap_delete__ns1__UploadAdditionalInfo(&m_WebService, pRequest); + + if (!bReqOK) + throw runtime_error((const char*)CW2A(m_WebService.GetErrorText().c_str())); + + if (m_bStop) + throw std::runtime_error("canceled"); + + return result; + } + + void PrepareDump( + const CString& dumpFile, + const CString& zipFile, + HANDLE hProcess, + DWORD dwProcessId, + MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo, + MINIDUMP_TYPE type, + MINIDUMP_CALLBACK_INFORMATION* pCallback, + bool attachFiles) + { + if (m_bStop) + throw std::runtime_error("canceled"); + + g_Log.Info(_T("Writing dump (%s)..."), static_cast(dumpFile)); + if (!m_DumpWriter.WriteMiniDump(hProcess, dwProcessId, pExceptInfo, dumpFile, type, pCallback)) + throw std::runtime_error("dump was not created"); + g_Log.Info(_T("Dump ready.")); + + if (m_bStop) + throw std::runtime_error("canceled"); + + g_Log.Info(_T("Zipping dump (%s)..."), static_cast(zipFile)); + { + Zip zip(zipFile); + zip.AddFile(dumpFile, dumpFile.Mid(dumpFile.ReverseFind(_T('\\')) + 1)); + if (attachFiles) + { + CString crashInfoFile = m_TempFolder + _T("\\crashinfo.xml"); + if (m_CrashInfo->GetCrashInfoFile(crashInfoFile)) + g_Config.FilesToAttach.push_back(std::make_pair(crashInfoFile, L"crashinfo.xml")); + + CString crashUserInfoFile = m_TempFolder + _T("\\crashuserinfo.xml"); + if (g_Config.UserInfo.size()) + { + FILE* f = NULL; + if (0 == _tfopen_s(&f, crashUserInfoFile, _T("wt"))) + { + fprintf_s(f, "\n"); + for (auto it = g_Config.UserInfo.cbegin(), end = g_Config.UserInfo.cend(); it != end; ++it) + { + g_Log.Info(_T("Adding UserInfo \"%ls\" as \"%ls\"..."), static_cast(it->first), static_cast(it->second)); + fprintf_s(f, + "<%ls>%ls\n", + static_cast(it->first), + static_cast(it->second), + static_cast(it->first)); + } + fprintf_s(f, ""); + fclose(f); + g_Config.FilesToAttach.push_back(std::make_pair(crashUserInfoFile, L"crashuserinfo.xml")); + } + } + + WIN32_FIND_DATAW ff; + FindClose(FindFirstFileW(dumpFile, &ff)); + __int64 attachedSizeLimit = max(1024*1024I64, (static_cast<__int64>(ff.nFileSizeHigh) << 32) | ff.nFileSizeLow); + + g_Log.Info(_T("Adding %d attaches..."), g_Config.FilesToAttach.size()); + for (auto it = g_Config.FilesToAttach.begin(), end = g_Config.FilesToAttach.end(); it != end; ++it) + { + g_Log.Info(_T("Adding \"%ls\" as \"%ls\"..."), static_cast(it->first), static_cast(it->second)); + WIN32_FIND_DATAW ff; + HANDLE hFind = FindFirstFileW(it->first, &ff); + if (hFind == INVALID_HANDLE_VALUE) + { + g_Log.Warning(_T("File \"%ls\" not found..."), static_cast(it->first)); + continue; + } + FindClose(hFind); + __int64 size = (static_cast<__int64>(ff.nFileSizeHigh) << 32) | ff.nFileSizeLow; + if (size > attachedSizeLimit) + { + g_Log.Warning(_T("File \"%ls\" not skipped by size..."), static_cast(it->first)); + continue; + } + attachedSizeLimit -= size; + + zip.AddFile(it->first, it->second); + g_Log.Info(_T("Done.")); + } + DeleteFile(crashInfoFile); + } + } + g_Log.Info(_T("Zipping done.")); + + if (m_bStop) + throw std::runtime_error("canceled"); + } + + void PrepareMiniDump( + HANDLE hProcess, + DWORD dwProcessId, + MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo, + vector& modules) + { + g_Log.Info(_T("Prepare mini dump...")); + + DumpFilter dumpFilter(modules, pExceptInfo ? pExceptInfo->ThreadId : 0); + PrepareDump(m_MiniDumpFile, m_MiniDumpZipFile, hProcess, dwProcessId, pExceptInfo, MiniDumpFilterMemory, dumpFilter, false); + } + + void PrepareFullDump( + HANDLE hProcess, + DWORD dwProcessId, + MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo) + { + g_Log.Info(_T("Prepare full dump...")); + + PrepareDump(m_FullDumpFile, m_FullDumpZipFile, hProcess, dwProcessId, pExceptInfo, MiniDumpWithFullMemory, NULL, true); + } + + typedef bool (WINAPI *pfnCollectInfo)(LPCWSTR file, LPCWSTR cfg, HANDLE Process, DWORD ProcessId); + void PrepareAdditionalInfo(const Response& response, HANDLE Process, DWORD ProcessId) + { + g_Log.Info(_T("Prepare additional info...")); + HMODULE hInfoDll = NULL; + try + { + CAtlFile hFile(CreateFile(m_InfoDll, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); + if (hFile == INVALID_HANDLE_VALUE) + throw runtime_error("failed to create info.dll file"); + if (FAILED(hFile.Write(&response.infoModule[0], static_cast(response.infoModule.size())))) + throw runtime_error("failed to write info.dll file"); + hFile.Close(); + + hInfoDll = LoadLibrary(m_InfoDll); + if (!hInfoDll) + throw runtime_error("failed to load info.dll"); + + pfnCollectInfo CollectInfo = (pfnCollectInfo) GetProcAddress(hInfoDll, "CollectInfo"); + if (!CollectInfo) + throw runtime_error("failed to get CollectInfo from info.dll"); + + if (!CollectInfo(m_InfoFile, response.infoModuleCfg.c_str(), Process, ProcessId)) + throw runtime_error("CollectInfo failed"); + + FreeLibrary(hInfoDll); + DeleteFile(m_InfoDll); + } + catch (...) + { + if (hInfoDll) + FreeLibrary(hInfoDll); + DeleteFile(m_InfoDll); + throw; + } + } + + static CAtlStringW ToString(int n) + { + CAtlStringW result; + result.Format(L"%i", n); + return result; + } + + void ProcessSolution(const Solution& solution, const std::wstring& clientID, int problemID, int dumpGroupID, int dumpID) + { + g_Log.Info(_T("Process solution...")); + switch (solution.type) + { + case ns1__SolutionType__Url: + if (!solution.askConfirmation || IDOK == CSolutionDlg(g_Config.AppName, g_Config.Company, IDS_SOLUTION_URL).DoModal()) + { + CAtlStringW url = solution.url.c_str(); + url.Replace(L"{ClientID}", clientID.c_str()); + url.Replace(L"{ProblemID}", ToString(problemID)); + url.Replace(L"{DumpGroupID}", ToString(dumpGroupID)); + url.Replace(L"{DumpID}", ToString(dumpID)); + ShellExecute(NULL, _T("open"), CW2CT(url), NULL, NULL, SW_SHOWNORMAL); + } + break; + case ns1__SolutionType__Exe: + if (!solution.askConfirmation || IDOK == CSolutionDlg(g_Config.AppName, g_Config.Company, IDS_SOLUTION_EXE).DoModal()) + { + CAtlFile hFile(CreateFile(m_Patch, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); + if (hFile == INVALID_HANDLE_VALUE) + throw runtime_error("failed to create solution.exe file"); + if (FAILED(hFile.Write(&solution.exe[0], static_cast(solution.exe.size())))) + throw runtime_error("failed to write solution.exe file"); + hFile.Close(); + + STARTUPINFO si = {}; + si.cb = sizeof(si); + PROCESS_INFORMATION pi = {}; + if (!CreateProcess(NULL, m_Patch.GetBuffer(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + throw runtime_error("failed to start solution.exe"); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + break; + default: + throw runtime_error("Unknown SolutionType"); + } + } + + void SendReportDlgThread() + { + CSendReportDlg dlg(g_Config.AppName, g_Config.Company); + assert(!m_pProgressDlg); + m_pProgressDlg = &dlg; + if (dlg.DoModal() == IDCANCEL) + m_bStop = true; + m_pProgressDlg = NULL; + } + + static DWORD WINAPI _SendReportDlgThread(LPVOID param) + { + static_cast(param)->SendReportDlgThread(); + return 0; + } + + void SendAssertReportDlgThread() + { + CSendAssertReportDlg dlg(g_Config.AppName, g_Config.Company); + assert(!m_pProgressDlg); + m_pProgressDlg = &dlg; + if (dlg.DoModal() == IDCANCEL) + m_bStop = true; + m_pProgressDlg = NULL; + } + + static DWORD WINAPI _SendAssertReportDlgThread(LPVOID param) + { + static_cast(param)->SendAssertReportDlgThread(); + return 0; + } + + void SendFullDumpDlgThread() + { + CSendFullDumpDlg dlg(g_Config.AppName, g_Config.Company); + assert(!m_pProgressDlg); + m_pProgressDlg = &dlg; + if (dlg.DoModal() == IDCANCEL) + m_bStop = true; + m_pProgressDlg = NULL; + } + + static DWORD WINAPI _SendFullDumpDlgThread(LPVOID param) + { + static_cast(param)->SendFullDumpDlgThread(); + return 0; + } + + void CloseProgress(HANDLE hThread, bool bCancel = true) + { + if (!hThread) + return; + Sleep(100); // It could be that m_pProgressDlg->DoModal not yet created a window + if (m_pProgressDlg) + m_pProgressDlg->PostMessage(WM_CLOSE); + WaitForSingleObject(hThread, INFINITE); + if (!bCancel) + m_bStop = false; + } + + bool Process(HANDLE hProcess, DWORD dwProcessId, MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo, bool wasAssert, HANDLE hReportReady) + { + m_DumpWriter.Init(); + + // we need to get CrashInfo before writing the dumps, since dumps writing will change WorkingSet + m_CrashInfo.reset(new CrashInfo(hProcess)); + + InitPathes(); + + HANDLE hThreadTemp = NULL; + if (!g_Config.ServiceMode) + { + DWORD t; + hThreadTemp = CreateThread(NULL, 0, wasAssert ? _SendAssertReportDlgThread : _SendReportDlgThread, this, 0, &t); + if (!hThreadTemp) + throw runtime_error("Failed to create thread"); + } + CHandle hShowProgressThread(hThreadTemp); + wstring urlToProblem; + std::wstring clientID; + int problemID = 0; + int dumpGroupID = 0; + int dumpID = 0; + +#if 0 + // This code is for test purposes + { + CloseProgress(hShowProgressThread, false); + DWORD t; + CHandle hThreadTemp2(CreateThread(NULL, 0, _SendFullDumpDlgThread, this, 0, &t)); + if (!hThreadTemp2) + throw runtime_error("Failed to create thread"); + hShowProgressThread = hThreadTemp2; + Sleep(1000); // Give time to draw a dialog before writing a dump (it will freeze a process and a dialog) + for (int i = 0; m_pProgressDlg && i < 100; ++i) + { + m_pProgressDlg->PostMessage(WM_USER, 100, i); + Sleep(30); + } + throw runtime_error("end"); + } +#endif + + try + { + vector modules; + PrepareMiniDump(hProcess, dwProcessId, pExceptInfo, modules); + if (g_Config.ServiceMode) + { + PrepareFullDump(hProcess, dwProcessId, pExceptInfo); + TerminateProcess(hProcess, E_FAIL); // It is necessary for DUMPPARSER to terminate app, because it should process our dump, and it could not do it since it crashes. + CloseHandle(hProcess); + hProcess = NULL; + } + + bool additionalInfoAlreadyApproved = false; + + Response response = Hello(modules); + while (1) + { + switch (response.type) + { + case ns1__ResponseType__HaveSolution: + CloseProgress(hShowProgressThread); + if (response.solution.get()) + ProcessSolution(*response.solution, clientID, problemID, dumpGroupID, dumpID); + goto finish; + case ns1__ResponseType__NeedMiniDump: + response = UploadMiniDump(m_MiniDumpZipFile); + urlToProblem = response.urlToProblem; + clientID = response.clientID; + problemID = response.problemID; + dumpGroupID = response.dumpGroupID; + dumpID = response.dumpID; + continue; + case ns1__ResponseType__NeedMoreInfo: + { + CloseProgress(hShowProgressThread, false); + + if (!g_Config.ServiceMode) + { + if (!additionalInfoAlreadyApproved && CAskSendFullDumpDlg(g_Config.AppName, g_Config.Company, g_Config.PrivacyPolicyUrl).DoModal() == IDCANCEL) + { + response = SendAdditionalInfoUploadRejected(response.dumpID); + continue; + } + additionalInfoAlreadyApproved = true; + + DWORD t; + CHandle hThreadTemp2(CreateThread(NULL, 0, _SendFullDumpDlgThread, this, 0, &t)); + if (!hThreadTemp2) + throw runtime_error("Failed to create thread"); + hShowProgressThread = hThreadTemp2; + Sleep(100); // Give time to draw a dialog before writing a dump (it will freeze a process and a dialog) + } + + if (response.infoType == ns1__AdditionalInfoType__FullDump) + { + if (!g_Config.ServiceMode) + { + PrepareFullDump(hProcess, dwProcessId, pExceptInfo); + CloseHandle(hProcess); + hProcess = NULL; + } + SetEvent(hReportReady); + response = UploadAdditionalInfo(response.dumpID, m_FullDumpZipFile, true); + } + else if (response.infoType == ns1__AdditionalInfoType__Info) + { + PrepareAdditionalInfo(response, hProcess, dwProcessId); + response = UploadAdditionalInfo(response.dumpID, m_InfoFile, false); + } + else + { + throw runtime_error("Unknown AdditionalInfoType"); + } + } + continue; + case ns1__ResponseType__Error: + throw runtime_error((const char*)CW2A(response.error.c_str())); + case ns1__ResponseType__Stop: + default: + goto finish; + } + } +finish: + if (!g_Config.ServiceMode && !urlToProblem.empty() && g_Config.OpenProblemInBrowser) + ShellExecute(NULL, _T("open"), CW2CT(urlToProblem.c_str()), NULL, NULL, SW_SHOWNORMAL); + } + catch (...) + { + CloseProgress(hShowProgressThread); + throw; + } + + CloseProgress(hShowProgressThread); + + return true; + } +}; + +DWORD SendReportImpl(HANDLE hProcess, DWORD dwProcessId, MINIDUMP_EXCEPTION_INFORMATION* mei, bool wasAssert, HANDLE hReportReady) +{ + try + { + g_Log.Info(_T("SENDRPT was invoked to send report, PID 0x%x"), dwProcessId); + CrashProcessor().Process(hProcess, dwProcessId, mei, wasAssert, hReportReady); + } + catch (std::exception& ex) + { + g_Log.Error(_T("Problem occured: %hs"), ex.what()); + OutputDebugStringA(ex.what()); +//#ifdef _DEBUG + ::MessageBoxA(0, ex.what(), "SendRpt: Error", MB_ICONERROR); +//#endif + return FALSE; + } + return TRUE; +} + +int __cdecl SendReport(int argc, wchar_t* argv[]) +{ + CRegKey reg; + if (ERROR_SUCCESS == reg.Open(HKEY_LOCAL_MACHINE, _T("Software\\Idol Software\\DumpUploader"), KEY_READ)) + { + DWORD attachDebugger = FALSE; + reg.QueryDWORDValue(_T("AttachDebugger"), attachDebugger); + if (attachDebugger != FALSE) + { + if (IDYES == ::MessageBoxA(0, "Do you want to debug?\n\nYour should attach debugger to sendrpt.exe before choosing Yes.", "SendRpt: SendReport", MB_ICONWARNING | MB_YESNO)) + DebugBreak(); + } + + DWORD traceEnable = FALSE; + if (ERROR_SUCCESS == reg.QueryDWORDValue(_T("TraceEnable"), traceEnable) && traceEnable != FALSE) + { + CString str; + ULONG size = 1000; + if (ERROR_SUCCESS == reg.QueryStringValue(_T("TraceFolder"), str.GetBuffer(size), &size)) + { + str.ReleaseBuffer(size-1); + InitializeLog(); + g_Log.SetParams(LogMediaPtr(new FileMedia(str + _T("\\sendrpt.log"), true, false))); + } + } + } + + Params params; + + Serializer ser(argv[1]); + ser << params << g_Config; + params.ExceptInfo.ClientPointers = TRUE; + + return SendReportImpl(params.Process, params.ProcessId, ¶ms.ExceptInfo, !!params.WasAssert, params.ReportReady); +} \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/DumpWriter.cpp b/ext/CrashServer/CrashHandler/SendRpt/DumpWriter.cpp new file mode 100644 index 000000000..5a76f4180 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/DumpWriter.cpp @@ -0,0 +1,121 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "StdAfx.h" +#include "resource.h" +#include "DumpWriter.h" +#include "..\..\CommonLibs\Log\log.h" + +using namespace std; + +extern Log g_Log; + +static void ExtractFileFromResource(HMODULE hImage, DWORD resId, LPCTSTR path) +{ + g_Log.Debug(_T("Extracting resource %d to \"%s\"..."), resId, path); + HRSRC hDbghelpRes = FindResource(hImage, MAKEINTRESOURCE(resId), RT_RCDATA); + if (!hDbghelpRes) + throw runtime_error("failed to find file in resources"); + + HGLOBAL hDbghelpGlobal = LoadResource(hImage, hDbghelpRes); + if (!hDbghelpGlobal) + throw runtime_error("failed to load file from resources"); + + CAtlFile hFile(CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); + if (hFile == INVALID_HANDLE_VALUE) + throw runtime_error("failed to create file"); + + if (FAILED(hFile.Write(LockResource(hDbghelpGlobal), SizeofResource(hImage, hDbghelpRes)))) + throw runtime_error("failed to write file"); +} + +DumpWriter::DumpWriter() + : m_hDbgHelp(NULL) + , m_pfnMiniDumpWriteDump(NULL) +{ +} + +DumpWriter::~DumpWriter() +{ + m_pfnMiniDumpWriteDump = NULL; + if (m_hDbgHelp) + { + FreeLibrary(m_hDbgHelp); + m_hDbgHelp = NULL; + DeleteFile(m_szDbghelpPath); + } +} + +void DumpWriter::CreateDbghelp() +{ + TCHAR szTempPath[MAX_PATH]; + GetTempPath(_countof(szTempPath), szTempPath); + GetTempFileName(szTempPath, _T("dbg"), 0, m_szDbghelpPath); + DWORD resid = IDR_DBGHELP; +#ifdef USE64 + resid = IDR_DBGHELPX64; +#endif + ExtractFileFromResource(GetModuleHandle(NULL), resid, m_szDbghelpPath); +} + +void DumpWriter::Init() +{ + CreateDbghelp(); + m_hDbgHelp = LoadLibrary(m_szDbghelpPath); + if (!m_hDbgHelp) + throw runtime_error("failed to load dbghelp.dll"); + + m_pfnMiniDumpWriteDump = (fnMiniDumpWriteDump) GetProcAddress(m_hDbgHelp, "MiniDumpWriteDump"); + if (!m_pfnMiniDumpWriteDump) + throw runtime_error("failed to get MiniDumpWriteDump"); +} + +bool DumpWriter::WriteMiniDump( + HANDLE hProcess, + DWORD dwProcessId, + MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo, + LPCTSTR pszFileName, + MINIDUMP_TYPE DumpType, + MINIDUMP_CALLBACK_INFORMATION* pCallback) +{ + if (!m_pfnMiniDumpWriteDump) + return false; + + HANDLE hFile = CreateFile(pszFileName, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_FLAG_WRITE_THROUGH, + NULL); + + if (hFile == INVALID_HANDLE_VALUE) + return false; + + bool result = m_pfnMiniDumpWriteDump(hProcess, dwProcessId, + hFile, DumpType, pExceptInfo, NULL, pCallback) != FALSE; + + if (result) + { + DWORD dwFileSize = GetFileSize(hFile, NULL); + result = dwFileSize != INVALID_FILE_SIZE && dwFileSize > 1024; + } + + CloseHandle(hFile); + + return result; +} diff --git a/ext/CrashServer/CrashHandler/SendRpt/DumpWriter.h b/ext/CrashServer/CrashHandler/SendRpt/DumpWriter.h new file mode 100644 index 000000000..9fc1580a8 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/DumpWriter.h @@ -0,0 +1,54 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include + +class DumpWriter +{ +public: + DumpWriter(); + ~DumpWriter(); + + void Init(); + + bool WriteMiniDump( + HANDLE hProcess, + DWORD dwProcessId, + MINIDUMP_EXCEPTION_INFORMATION* pExceptInfo, + LPCTSTR pszFileName, + MINIDUMP_TYPE DumpType, + MINIDUMP_CALLBACK_INFORMATION* pCallback); + +private: + void CreateDbghelp(); + + typedef BOOL (WINAPI *fnMiniDumpWriteDump)( + IN HANDLE hProcess, + IN DWORD ProcessId, + IN HANDLE hFile, + IN MINIDUMP_TYPE DumpType, + IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL + IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL + IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL); + + TCHAR m_szDbghelpPath[MAX_PATH]; + HINSTANCE m_hDbgHelp; + fnMiniDumpWriteDump m_pfnMiniDumpWriteDump; +}; diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.cpp b/ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.cpp new file mode 100644 index 000000000..26995c52e --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.cpp @@ -0,0 +1,167 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "StdAfx.h" +#include "SendReportDlg.h" + +LRESULT CStaticEx::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + PAINTSTRUCT ps; + CDCHandle dc(BeginPaint(&ps)); + + dc.SetTextColor(m_TextColor); + + CFontHandle font(GetFont()); + dc.SelectFont(font); + + RECT rect; + GetClientRect(&rect); + + CString text; + GetWindowText(text); + dc.DrawText(text, -1, &rect, DT_END_ELLIPSIS | DT_WORDBREAK); + + EndPaint(&ps); + + bHandled = TRUE; + + return 0; +} + +LRESULT CSolutionDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + LRESULT res = Base::OnInitDialog(uMsg, wParam, lParam, bHandled); + GetDlgItem(IDC_QUESTION).SetWindowText(m_question); + SubstituteText(GetDlgItem(IDC_QUESTION)); + + m_Quest.m_TextColor = CDC(GetDlgItem(IDC_QUESTION).GetDC()).GetTextColor(); + m_Quest.SubclassWindow(GetDlgItem(IDC_QUESTION)); + + return res; +} + +LRESULT CSendFullDumpDlg::OnSetProgress(UINT uMsg, WPARAM wTotal, LPARAM lSent, BOOL& bHandled) +{ + if (m_Progress.IsWindow()) + { + if (!m_progressBegan) + { + m_Text.LockWindowUpdate(); // without that CStaticEx::OnPaint doesn't called ??? + m_Text.SetWindowText(SubstituteText(CString((LPCSTR)IDS_SENDING_DATA))); + m_Text.LockWindowUpdate(FALSE); + m_Progress.ModifyStyle(PBS_MARQUEE, 0); + m_Progress.SetRange(0, 1000); // 1000 to make moving smooth (not less than pixels in progress bar) + m_progressBegan = true; + } + m_Progress.SetPos(int((1000.0 * lSent) / wTotal)); + } + return 0; +} + +LRESULT CAskSendFullDumpDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + Base::OnInitDialog(uMsg, wParam, lParam, bHandled); + RECT rect_client, rect_main, rect_details; + GetClientRect(&rect_client); + ClientToScreen(&rect_client); + GetWindowRect(&rect_main); + GetDlgItem(IDC_DETAILS).GetWindowRect(&rect_details); + m_nWidth = rect_client.right - rect_client.left; + m_nFullHeight = rect_client.bottom - rect_client.top; + int nNewHeight = rect_details.bottom - rect_client.top + 8; + + ResizeClient(m_nWidth, nNewHeight); + + m_Details = GetDlgItem(IDC_DETAILS_TEXT); + m_Details.SetEventMask(ENM_LINK); + + CString text((LPCSTR)IDS_PRIVATE_INFO_TEXT); + + SetDetailsText(text); + + return 0; +} + +void CAskSendFullDumpDlg::SetDetailsText(const CString &text) +{ + CString clearText = text; + std::vector> links; + int pos; + while ((pos = clearText.Find(_T(""))) != -1) + { + DWORD beg = pos; + clearText.Delete(pos, 3); + pos = clearText.Find(_T("")); + if (pos != -1) + { + links.push_back(std::make_pair(beg, DWORD(pos))); + clearText.Delete(pos, 4); + } + } + + m_Details.SetWindowTextW(clearText); + + CHARRANGE sel; + m_Details.GetSel(sel); + + CHARFORMAT2 cf; + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_LINK | CFM_WEIGHT; + cf.dwEffects = CFE_LINK; + cf.wWeight = FW_BOLD; + + for (size_t i = 0; i < links.size(); ++i) + { + m_Details.SetSel(links[i].first, links[i].second); + m_Details.SetWordCharFormat(cf); + } + + m_Details.SetSel(sel); +} + +LRESULT CAskSendFullDumpDlg::OnClickedDetails(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + ResizeClient(m_nWidth, m_nFullHeight); + GetDlgItem(IDC_DETAILS).EnableWindow(FALSE); + return 0; +} + +LRESULT CAskSendFullDumpDlg::OnLinkClicked(int windowId, LPNMHDR wParam, BOOL& bHandled) +{ + ENLINK* enLink = (ENLINK*) wParam; + if (enLink->msg != WM_LBUTTONUP) + return 0; + + if (!m_url.IsEmpty()) + ShellExecute(NULL, _T("open"), CW2CT(m_url), NULL, NULL, SW_SHOWNORMAL); + + bHandled = TRUE; + + return 0; +} + +LRESULT CAskSendFullDumpDlg::OnClickedOKCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + if (wID == IDCANCEL) + { + CString motivation(MAKEINTRESOURCE(IDS_MOTIVATE_TO_SEND_FULL)); + if (IDNO == MessageBox(SubstituteText(motivation), SubstituteText(_T("[AppName]")), MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2)) + return 0; + } + EndDialog(wID); + return 0; +} diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.h b/ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.h new file mode 100644 index 000000000..45ba2c8a0 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendReportDlg.h @@ -0,0 +1,208 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include "resource.h" // main symbols + +#include +#include +#include +#include + + +class CStaticEx: public CWindowImpl +{ +public: + BEGIN_MSG_MAP(CStaticEx) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + END_MSG_MAP() + + COLORREF m_TextColor; + + LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); +}; + +// CBaseDlgT + +template +class CBaseDlgT : + public CAxDialogImpl > +{ + CString m_AppName, m_Company; + HFONT m_Big; + CStaticEx m_Header; +protected: + typedef CBaseDlgT Base; + CStaticEx m_Text; + CProgressBarCtrl m_Progress; +public: + CBaseDlgT(const wchar_t* pszAppName, const wchar_t* pszCompany) + : m_AppName(pszAppName), m_Company(pszCompany) + { + } + + enum { IDD = T }; + + BEGIN_MSG_MAP(CBaseDlgT) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_HANDLER(IDOK, BN_CLICKED, OnClickedOKCancel) + COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnClickedOKCancel) + CHAIN_MSG_MAP(CAxDialogImpl >) + END_MSG_MAP() + + // Handler prototypes: + // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); + + CString SubstituteText(const CString& text) + { + CString res = text; + res.Replace(_T("[AppName]"), m_AppName); + res.Replace(_T("[Company]"), m_Company); + return res; + } + + void SubstituteText(CWindow& window) + { + CString text; + window.GetWindowText(text); + window.SetWindowText(SubstituteText(text)); + } + + virtual LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + CAxDialogImpl >::OnInitDialog(uMsg, wParam, lParam, bHandled); + bHandled = TRUE; + SetIcon(::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SENDRPT))); + + HFONT hFont = GetFont(); + LOGFONT lf; + GetObject(hFont, sizeof(lf), &lf); + lf.lfWeight = FW_THIN; + lf.lfHeight = 20; + m_Big = CreateFontIndirect(&lf); + + SubstituteText(*this); + SubstituteText(GetDlgItem(IDC_HEADER_TEXT)); + SubstituteText(GetDlgItem(IDC_TEXT)); + + GetDlgItem(IDC_HEADER_TEXT).SetFont(m_Big); + m_Header.SubclassWindow(GetDlgItem(IDC_HEADER_TEXT)); + m_Header.m_TextColor = RGB(0, 0x33, 0x99); + + m_Text.m_TextColor = CDC(GetDlgItem(IDC_TEXT).GetDC()).GetTextColor(); + m_Text.SubclassWindow(GetDlgItem(IDC_TEXT)); + + m_Progress = GetDlgItem(IDC_PROGRESS); + if (m_Progress.IsWindow()) + m_Progress.SetMarquee(TRUE); + + return 1; // Let the system set the focus + } + + virtual LRESULT OnClickedOKCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) + { + EndDialog(wID); + return 0; + } +}; + + +// CSendReportDlg + +class CSendReportDlg : public CBaseDlgT +{ +public: + CSendReportDlg(const wchar_t* pszAppName, const wchar_t* pszCompany) + : CBaseDlgT(pszAppName, pszCompany) + { + } +}; + +// CSendAssertReportDlg + +class CSendAssertReportDlg : public CBaseDlgT +{ +public: + CSendAssertReportDlg(const wchar_t* pszAppName, const wchar_t* pszCompany) + : CBaseDlgT(pszAppName, pszCompany) + { + } +}; + +// CSendFullDumpDlg + +class CSendFullDumpDlg : public CBaseDlgT +{ + bool m_progressBegan; +public: + CSendFullDumpDlg(const wchar_t* pszAppName, const wchar_t* pszCompany) + : CBaseDlgT(pszAppName, pszCompany), m_progressBegan(false) + { + } + + BEGIN_MSG_MAP(CSendFullDumpDlg) + MESSAGE_HANDLER(WM_USER, OnSetProgress) + CHAIN_MSG_MAP(Base) + END_MSG_MAP() + + LRESULT OnSetProgress(UINT uMsg, WPARAM wTotal, LPARAM lSent, BOOL& bHandled); +}; + +// CSolutionDlg + +class CSolutionDlg : public CBaseDlgT +{ + CStaticEx m_Quest; + CString m_question; +public: + CSolutionDlg(const wchar_t* pszAppName, const wchar_t* pszCompany, DWORD question) + : CBaseDlgT(pszAppName, pszCompany), m_question(MAKEINTRESOURCE(question)) + { + } + + LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) override; +}; + +// CAskSendFullDumpDlg + +class CAskSendFullDumpDlg : public CBaseDlgT +{ + int m_nWidth, m_nFullHeight; + CRichEditCtrl m_Details; + CString m_url; +public: + CAskSendFullDumpDlg(const wchar_t* pszAppName, const wchar_t* pszCompany, const wchar_t* pszUrl) + : CBaseDlgT(pszAppName, pszCompany), m_url(pszUrl) + { + } + + BEGIN_MSG_MAP(CAskSendFullDumpDlg) + COMMAND_HANDLER(IDC_DETAILS, BN_CLICKED, OnClickedDetails) + NOTIFY_HANDLER(IDC_DETAILS_TEXT, EN_LINK, OnLinkClicked) + CHAIN_MSG_MAP(Base) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) override; + void SetDetailsText(const CString &text); + LRESULT OnClickedDetails(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + LRESULT OnLinkClicked(int windowId, LPNMHDR wParam, BOOL& bHandled); + LRESULT OnClickedOKCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) override; +}; + diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendRpt.cpp b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.cpp new file mode 100644 index 000000000..73b8c234c --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.cpp @@ -0,0 +1,59 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "StdAfx.h" +#include +#include +#include "SendReportDlg.h" + +#ifdef _UNICODE +# if defined _M_IX86 +# pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +# elif defined _M_IA64 +# pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") +# elif defined _M_X64 +# pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +# else +# pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +# endif +#endif + +int __cdecl SendReport(int argc, wchar_t* argv[]); + +int APIENTRY wWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + setlocale(LC_ALL, ".ACP"); + + LoadLibrary(_T("riched20")); + + // CAskSendFullDumpDlg(L"Sample App", L"Idol Software", L"http://www.idolsoftware.ru").DoModal(); return 0; + + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + + if (argc != 2) + return 0; + + int res = SendReport(argc, argv); + + TerminateProcess(GetCurrentProcess(), res); + + return res; +} diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendRpt.ico b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.ico new file mode 100644 index 0000000000000000000000000000000000000000..eb91e8abea0323b3a77681371a05d01c8dc68b6a GIT binary patch literal 3638 zcwX(6drXsO6vm&gh%#6iI-^cm1V;cX6qFSDTwWYxv^I3* z3aH)#O8tS71%!~GaWRc+q6E-HdZRFWF6xv~IIE1u@}*)NUIZKrAQl4U6n~6&$LTme zeu(kJ$>`~5E{wpb?3HLLSck^^NHpwUk7ZP+mC-(dKvsY)&Tr)5?B{N1D_(<^qP3`B z3sjPSBnW8S?1Y9SXIxBl!8O$?=*q&;xE{E)j))}KaTE~^G*GOMAZYG9>&IH+O0qqg zQ=M>i8xOiH9&Y9Nptr~uzpI33%ASQTr5|pWNzq#oitfW7xXH4#5CN^b4MG!?mK%ua7XEZ z`}@7nyUz;`iUsJ+_r{%k0qzyhH5qsZy@j*r`sUzXi7&3~@Q6Xrb70`8Yv&(+ON{KaKWlb$F=P;}P+g z_>=gHctZ3M{D>#eQ%p-sLqb9VLPA358?Hxcsva*jRLqN)=2>Ex*Q{+w*2Bf+(v!1> z8DnK(lA6_EW@TZgVeHjL9c7{(~zG`-@DzdYG>s@B`K6 z4F-JU^)EK_)kA#s(|&&gvvT!nbKmqHRSitA{tC63hJF6w_@k}*0Ct7>V@Iezbk!wz^x!@!qkWJU?uXpfLgcIxqO-OT z9W_PhIbDdZlliC(wLxtd%d0r?8J8lLqAg*EbMX#1ljw@N?Q>C(v<%(f@53L|vv##D zI*w)Fs3H+Jb~@o^jx&DU!$Wt@G~AREId16Q2m?=88ljsYJq& zNTed6&{{m+kQyWv3T?&Xj5)`Y3nl%zq(3KL%8{CUvwW<00(I^0FJyC9Uy@;e-`TTg tIf?BZ?E5vvaSSt6>@5)R`5t^ekLTegcuVlStEJzy@qhGRi80o({0+>",IDC_DETAILS,5,74,50,14 +END + +IDD_SOLUTIONDLG DIALOGEX 0, 0, 211, 92 +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "[AppName]" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_STATIC,"Static",SS_WHITERECT,-4,0,214,67 + PUSHBUTTON "No",IDCANCEL,156,73,50,14 + CONTROL "[AppName] has stopped working",IDC_HEADER_TEXT,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,5,7,201,25 + LTEXT "Solution to the problem has been found.",IDC_TEXT,5,35,201,8 + LTEXT "www.crash-server.com",IDC_STATIC,5,76,75,8,WS_DISABLED + LTEXT "Static",IDC_QUESTION,5,49,201,8 + PUSHBUTTON "Yes",IDOK,103,73,50,14 +END + +IDD_SENDASSERTREPORTDLG DIALOGEX 0, 0, 211, 92 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "[AppName]" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_STATIC,"Static",SS_WHITERECT,-4,0,214,67 + PUSHBUTTON "Cancel",IDCANCEL,156,73,50,14 + CONTROL "[AppName] has encountered a problem",IDC_HEADER_TEXT, + "Static",SS_LEFTNOWORDWRAP | WS_GROUP,5,7,201,25 + LTEXT "Sending crash data...",IDC_TEXT,5,35,201,8 + CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_MARQUEE | WS_BORDER,5,49,201,10 + LTEXT "www.crash-server.com",IDC_STATIC,5,76,75,8,WS_DISABLED +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SENDREPORTDLG, DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 206 + BOTTOMMARGIN, 87 + HORZGUIDE, 7 + HORZGUIDE, 35 + HORZGUIDE, 49 + HORZGUIDE, 80 + END + + IDD_SENDFULLDUMPDLG, DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 206 + BOTTOMMARGIN, 96 + HORZGUIDE, 7 + HORZGUIDE, 35 + HORZGUIDE, 58 + END + + IDD_ASKSENDFULLDUMPDLG, DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 206 + BOTTOMMARGIN, 171 + HORZGUIDE, 7 + HORZGUIDE, 37 + HORZGUIDE, 74 + HORZGUIDE, 96 + END + + IDD_SOLUTIONDLG, DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 206 + BOTTOMMARGIN, 87 + HORZGUIDE, 7 + HORZGUIDE, 35 + HORZGUIDE, 49 + HORZGUIDE, 80 + END + + IDD_SENDASSERTREPORTDLG, DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 206 + BOTTOMMARGIN, 87 + HORZGUIDE, 7 + HORZGUIDE, 35 + HORZGUIDE, 49 + HORZGUIDE, 80 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_PRIVATE_INFO_TEXT "Read our privacy statement\n\nReport contains application state at the moment of failure\nincluding all memory. Report may unintentionally contain\npersonal information, but this information is not used to\nidentify you or contact you. For example, a report may\ninclude your name, part of a document you were working\non, or data that you recently submitted to a website. If\nyou are concerned that a report may contain personal or\nconfidential information, you should not send the report." + IDS_SOLUTION_URL "Do you want to read it?" + IDS_SOLUTION_EXE "Do you want to install it?" + IDS_MOTIVATE_TO_SEND_FULL + "This problem occurs first time and [Company] really need this report to fix the problem in a future version of [AppName].\nAre you sure you don't want to send it?" + IDS_SENDING_DATA "Sending collected information to the [Company].\nThis might take several minutes..." +END + +#endif // English resources +///////////////////////////////////////////////////////////////////////////// + + diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj new file mode 100644 index 000000000..b39e42de4 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj @@ -0,0 +1,230 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {60557EDD-7D52-4200-8884-7541105387F9} + SendRpt + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + true + true + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + Level3 + EditAndContinue + + + version.lib;%(AdditionalDependencies) + true + Windows + + + MachineX86 + + + + + + Disabled + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + USE64;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebug + Use + Level3 + ProgramDatabase + + + version.lib;%(AdditionalDependencies) + true + Windows + + + + + USE64;%(PreprocessorDefinitions) + + + + + MaxSpeed + true + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + true + Use + Level3 + ProgramDatabase + + + version.lib;%(AdditionalDependencies) + true + Windows + true + true + + + MachineX86 + + + + + + MaxSpeed + true + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + USE64;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + true + Use + Level3 + ProgramDatabase + + + version.lib;%(AdditionalDependencies) + true + Windows + true + true + + + + + USE64;%(PreprocessorDefinitions) + + + + + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {4137c5c7-7e4d-4071-ada2-7052550a9e5d} + + + {eea8e6f4-76f0-42f7-a139-725c0b368a36} + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj.filters b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj.filters new file mode 100644 index 000000000..5829751b2 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendRpt.vcxproj.filters @@ -0,0 +1,93 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + + + Resource Files + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj b/ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj new file mode 100644 index 000000000..3c8b77f77 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj @@ -0,0 +1,231 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {944584E3-CE8D-42B6-AEAF-12F44FB15F13} + SendRptM + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + true + true + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + NO_DBGHELP;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + Level3 + EditAndContinue + + + version.lib;%(AdditionalDependencies) + true + Windows + + + MachineX86 + + + NO_DBGHELP;%(PreprocessorDefinitions) + + + + + Disabled + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + NO_DBGHELP;USE64;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebug + Use + Level3 + ProgramDatabase + + + version.lib;%(AdditionalDependencies) + true + Windows + + + + + NO_DBGHELP;USE64;%(PreprocessorDefinitions) + + + + + MinSpace + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + NO_DBGHELP;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + true + Use + Level3 + ProgramDatabase + + + version.lib;%(AdditionalDependencies) + true + Windows + true + true + + + MachineX86 + + + NO_DBGHELP;%(PreprocessorDefinitions) + + + + + MaxSpeed + true + $(GsoapDir);$(ExternalDir)wtl\include;%(AdditionalIncludeDirectories) + NO_DBGHELP;USE64;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + true + Use + Level3 + ProgramDatabase + + + version.lib;%(AdditionalDependencies) + true + Windows + true + true + + + + + NO_DBGHELP;USE64;%(PreprocessorDefinitions) + + + + + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + {4137c5c7-7e4d-4071-ada2-7052550a9e5d} + + + {eea8e6f4-76f0-42f7-a139-725c0b368a36} + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj.filters b/ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj.filters new file mode 100644 index 000000000..fec72572e --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/SendRptM.vcxproj.filters @@ -0,0 +1,91 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/Serializer.cpp b/ext/CrashServer/CrashHandler/SendRpt/Serializer.cpp new file mode 100644 index 000000000..eb296af8e --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/Serializer.cpp @@ -0,0 +1,132 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "StdAfx.h" +#include "Serializer.h" + +CString Serializer::GetHex() const +{ + CString res; + for (size_t i = 0, size = m_storage.size(); i < size; ++i) + res.AppendFormat(_T("%02X"), (DWORD)m_storage[i]); + return res; +} + +Serializer::Serializer() : m_buf(NULL), m_size(0) {} + +Serializer::Serializer(const CString& hex) +{ + size_t bufLen = hex.GetLength() / 2; + for (size_t i = 0; i < bufLen; ++i) + { + DWORD t; + if (1 != swscanf_s((LPCTSTR)hex + i * 2, L"%02X", &t)) + throw std::runtime_error("invalid buffer"); + m_storage.push_back((BYTE)t); + } + m_buf = &m_storage[0]; + m_size = m_storage.size(); +} + +Serializer::Serializer(const BYTE* buf, size_t size) : m_buf(buf), m_size(size) {} + +Serializer& Serializer::SerSimpleType(BYTE* ptr, size_t size) +{ + if (m_buf) + { + if (m_size < size) + throw std::runtime_error("invalid buffer"); + memcpy(ptr, m_buf, size); + m_buf += size; + m_size -= size; + } + else + { + m_storage.insert(m_storage.end(), ptr, ptr + size); + } + return *this; +} + +Serializer& Serializer::operator << (CStringA& val) +{ + DWORD len = val.GetLength(); + SerSimpleType((BYTE*)&len, sizeof(len)); + SerSimpleType((BYTE*)val.GetBuffer(len), len * sizeof(char)); + val.ReleaseBuffer(len); + return *this; +} + +Serializer& Serializer::operator << (CStringW& val) +{ + DWORD len = val.GetLength(); + SerSimpleType((BYTE*)&len, sizeof(len)); + SerSimpleType((BYTE*)val.GetBuffer(len), len * sizeof(wchar_t)); + val.ReleaseBuffer(len); + return *this; +} + +Serializer& operator << (Serializer& ser, MINIDUMP_EXCEPTION_INFORMATION& val) +{ + ser.SerSimpleType((BYTE*)&val.ExceptionPointers, sizeof(val.ExceptionPointers)); + return ser << val.ThreadId << val.ClientPointers; +} + +template +Serializer& operator << (Serializer& ser, std::pair& val) +{ + return ser << val.first << val.second; +} + +template +Serializer& operator << (Serializer& ser, std::vector& val) +{ + size_t size = val.size(); + ser.SerSimpleType((BYTE*)&size, sizeof(size)); + if (ser.m_buf) + val.resize(size); + for (size_t i = 0; i < val.size(); ++i) + ser << val[i]; + return ser; +} + +Serializer& operator << (Serializer& ser, Config& cfg) +{ + return ser << cfg.Prefix + << cfg.AppName + << cfg.Company + << cfg.PrivacyPolicyUrl + << cfg.V[0] << cfg.V[1] << cfg.V[2] << cfg.V[3] + << cfg.Hotfix + << cfg.ApplicationGUID + << cfg.ServiceMode + << cfg.LeaveDumpFilesInTempFolder + << cfg.OpenProblemInBrowser + << cfg.UseWER + << cfg.SubmitterID + << cfg.ProcessName + << cfg.FilesToAttach + << cfg.UserInfo; +} + +Serializer& operator << (Serializer& ser, Params& param) +{ + return ser << param.Process + << param.ProcessId + << param.ExceptInfo + << param.WasAssert + << param.ReportReady; +} \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/SendRpt/Serializer.h b/ext/CrashServer/CrashHandler/SendRpt/Serializer.h new file mode 100644 index 000000000..60fa5f2bc --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/Serializer.h @@ -0,0 +1,49 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include "Config.h" + +class Serializer +{ + const BYTE* m_buf; + size_t m_size; + +public: + std::vector m_storage; + + CString GetHex() const; + Serializer(); + Serializer(const CString& hex); + Serializer(const BYTE* buf, size_t size); + + Serializer& SerSimpleType(BYTE* ptr, size_t size); + Serializer& operator << (BOOL& val) { return SerSimpleType((BYTE*)&val, sizeof(val)); } + Serializer& operator << (USHORT& val) { return SerSimpleType((BYTE*)&val, sizeof(val)); } + Serializer& operator << (DWORD& val) { return SerSimpleType((BYTE*)&val, sizeof(val)); } + Serializer& operator << (HANDLE& val) { return SerSimpleType((BYTE*)&val, sizeof(val)); } + Serializer& operator << (CStringA& val); + Serializer& operator << (CStringW& val); + + template + friend Serializer& operator << (Serializer& ser, T& val); +}; + +Serializer& operator << (Serializer& ser, MINIDUMP_EXCEPTION_INFORMATION& val); +Serializer& operator << (Serializer& ser, Config& cfg); +Serializer& operator << (Serializer& ser, Params& param); diff --git a/ext/CrashServer/CrashHandler/SendRpt/dbghelp_x64.dll b/ext/CrashServer/CrashHandler/SendRpt/dbghelp_x64.dll new file mode 100644 index 0000000000000000000000000000000000000000..f3bd78ff9d0dc5715ab995c4cf55264b0cb56591 GIT binary patch literal 1369936 zcwX$i4O~>k8b5wOUgbqp1oEY}LZd`OC8NaRUC;$qSe1;Dm*q_t*Z>vHZd6)SW>i*G zR#aNt@)ji~85(uDH!8Z3VPTPyaSO|m$_l&Q{LeY_o!vdd4lKI&_xb%lpWop6-RGI_ zJoC)VGjnFoo;@ddd5ttmk|Y=MI&(&nnk1T{q~VjFlO*|Gu-8{=^!)I`CMWHO7wQX( z$~C64(t@(=Voh##Nl9siCMQo*wz@=9RHBJXP1h8c8uDiP_>2yQjcpgL{JAUEh;|jj~%prmw&wBt^^~`4q$Mu=dV`TZ!XO1ZPyPo-0!AHQ`^31OU&um%`xd!;K zf@wv$g>pTjHtFIe$#AEuH2#krNle!-U8M1H_LQWR<0YxjS<%I{j3ynRyd9Q zZjzJoa+N4gstHg!Hz;!gAx25GrzKX_^2RLFw_&;CrKzN-N7{HPQdVjLq<*<3(*&va zS%Mw@k}gmt21s>RNm3QzPL@WHNF^PvlC(iLUdpnOJ+mUOvV!1}qVd!rx$Q1$jz*HQ zW*V|9vdQ~~uShUd5l$u%O2(^rQIga$(?p4i@1zaVc7pE@;zi9YD=*6>@0GS{Xx~XC z{x*1d#!^BIkn1CTAl*o?Y!EL-`hRK2)SXGk;5T3&unqV}HuS&_U_J10U^TD|m=Dwe zqk!SSX+VGA=`7d>HUjH_HNZ8%9AF|a9C#7X4|sY7{0DXdTY-(hr+~Ku%YYd`Eieu^ z8+bm@8+iIgir)Y`fGxlV;N!rJz)IjsU?wmDI2(8o&>Q&24X6*;3490m8t^G#HLwDB zBQOyd3JhR&ms9)==y5$oe_$|hHgF*@2WSHR1$Ymz7FZ8_9oP!&1bzcN36v0*qk$8F zbAfTdG~h~LC2%9K2KX$n8R&v`v($}t9{~On*bHn0)&n00-VUq;mH=~r%Yj;8Byct` z1gHUyWBm{O`8tYyz{9`};7;IEzz2aFf$M=LU?xxpOaNX3318_gE1Nb?x7x)|SPvGcWivGYjwBu^vWxyby20T7>Zy%@ZOI&tP)BuBa zQat@K#l8lLy4NW-??t(0iW^%fYV#;&eM@mOunE`>>;dvAvU#*ky`0!yOWrZb`@*i7 z&QjM!&MHn)$(n3qkwIh1CR@wAio7!NuDm?Yps6U;#L64YilX8?P5$bV+=`;ol9{7f zxu`G3Q@?;AQi-%$GLpYbmHd#B)kfo`mU`T(s_v}1t%@8#M%`I;=j~PguCDR%@tZbn zB73EK$|@`@^zd-6G?~_#OdcL& z%91~K57_VgN!<_8aZ96hNpoh;G#HJteES!d{rzP5q?m^fZa0-2xnX}rU3Eh8@;l>R zuD`kFrYTQvn4GXa!>dW3`oLD*?2N~A&wIb>+AV>rFN@vl9i2wV=@6S&R-ShsuxL*^W@QUfbee`ROZ@Xnt&Ue8V#y#maZ&}4nZ~t-Vi(mXw z^NZq|JhtBS?he<8%D%8acj|wNyKV1PhqsQ&N-Lk5eQ;_~VO;ecwI3ee9I^1Po9Fg@ z?DS;xPVcYBUGc@|Prr6}>v^|_PFb|$)>lpjA6!_tX#KlSPmcT{?uA<8lpl9ob3tEh zQQ}=6uUhzA>!staJM){*`HdfVJip+s)CYf>yzQ=kb;PZodD-jh-JVO?UF*{FXrL}M z{NC{eAFhj8v}fTn_k6MEu_Kq?T={`<-xUda(;k{NZQqO!)6-8pTmS2>l$rw{q^upAu95jPduETupcSzJAjC)hmqJeO;RtZQByDY~!BQ?$^JY6u0r-J^N-| zr@y{CGwWs7+b&+X$8Yv^KOM~;SH3*P_lHPB(&ql>-~VY+SJ3l6^*@@@vpuEpR6|GK zp)oh?+4#V7b5|aY*>e1rQ@{NB^qd2}y={k{xiIF=2P4194q6nq_CMDx-1*WI3D0>w z)xPPi6aJ&8XZ}++c75_I?LF83a=7pOy7Fwla;MCcjo%)d5HtPQqsd2CHeLSKdkc3z z8~$pF_NyuB&d0v?-?Ag=#ju$-ue+z|s?zK0zQ1UnZ_*15v%4;Q&&9Z{H2TSnU%eK; zz5ic}Z@uZMCyL+u;>J%ud~m@l``ho9Zh6FSO2U)JEB-ZhL7nE7`yZcjV95;=8vd-m zqBG`>khkLRk9qv+RTpm3Yj-@I@Q5kxwdAx*->hl9==Pg+Cl>A67v25B?uWFSGJ-Zt zsN1RCI(AIzt|uNOPqtr3mRNDVl7zW2HDLUP_RB-==Y%6^M0V3PpcUZ@OOmM)SLY zlYghU^AyGHUwSFn_8rA-&<6v1C8}?R+>i3X6KOqqDNibwDx`GsDwB%HtS^w&PPK!a-%<$Hv%KPDTdxa`?(hSh6!j7Fk}oxjTgnlkH-wj^B705{VhKg&p$xT zGlJLona|Mmq8-5j!}teY8|<<1+Ik*EEwJ}JwVq)wFp@*YAI{zYXOFitQhU6Ayq(aA zjR@}K^Zu;^V5o!b869kow^PN9Z+{3y(dUD3|^R6n_ymal>x z_Ial73YyQ4ujz8wLq0#g8IVhdV6@= z^pnNmMt5(Ue#W8PWZ-G=+Gl$W+5WBJL$|+TA(bO=;I~kD_{f<&U zcQ#XufIbn}`VHFANAXJm;9~cIP#Lu#L8dE29Z|)c}*a%3niLnNpmHQlp_^M6$Epo zQpq6Y5xxAbSTYg4QOcG|h&D-zljQRec|=o6@?)hm@?yzASQX^Ov}={K8x@Kz3FWd0 zi={lNlDu-I)!>v%g(Sbs%r7BzR1izqgi}bgtfYZhEhjpeE7zGrys`L8y?t5RZBl5C9+P4TLJ)hMly$7`+P-AuE8%gp0ro0Ep| z5?Rn%wNIn;njA&z6pQ8LeJN>=Mrlz2@l)njC}pi%%F3CDjdesQT(u6{YA@B-wVil+SWqCVg4^AnlhqWjT-Zno|OHxu0{4YM_LJQ z#4O$)F;CrZte33I@_k9m(s^aO1kaU|rN1=hxheZ4_k~9BAy*mIa-4&d^HwWb>s}}8 zH?eJ!Eb-2wAy=^}*BL|J$>XIX+9G9~^UP;0r9oEH6;H~{ah^-88wsb}jB*6a?J}9m zBqG9%R_9C0m57n+Dz>YH92=$N9qkqM{7ff0d7UsQQD2~}Ftior=5|=~b&4&cVvnU_ zVxtnR%av9M%4MT|+jh0+SEC?520brZ&zF`cy)O5^PO|hf-@o}vU&y_hsFKs6$tBUl zx4#^ETkWL!!R?Usw*1dQbg;-ZavXWaRw%Jd=d1Oq$I4VFM*ulOSxiex+^)B>Ysnit zgX9#$`N3?Kn@3D-Ke^Pf+L))A%GTA(F1xJ2Selb;Ql`IOgCOpm|( z{wAbYy?=;+%^nGgJ(X4X90uH8iO*rc)6myesn=Wn{6f#|>h)Fn8 z;9SvVt9|ynHrwX)LO)zT@;F?5jScGdpL~SkhF8_~bv#PthHVtXYblz5JAu+;IL@x6 zmQLJuv(Uik*;MAa7kmG3Yha`xfjqQ|#XX zzn`b*2V|+ep31}Z|D`_MrmHeM1 zEr2~SPfjW1{W4OMj^xWpPjC^@r6@Myh{w^&=Y<3!WsuJhI{3-&59RbonETq$Y~LUE zF7|xvyw+m(`%kVkU9ltg*mDmXo|;|#h41#J?sexMJJ?fw=)j}XwXb{b+wkgN+-Ed> z`@od9Y7BmRru?jFSeba!8^0Wm-oNpd&d(=)-}`0p;@zDm-`(`d9ZPGC<6G)i8P=c5 z`S0=f^6p8^bn-uBbj!`1Kjx2LeLU`K)0E7+(XU9`8=ZBq?52WeKkgkBxuDZ!(SJAj z99Xq`^o~F3cVA(weJ$qG_ul*>>QwX2uZ>-^S7#oH|H$Xl?(61%{L;>_L({I74lk}+ z{8?K-cE?-0Pc~k7aqF(7k3GEiqcJ=7H9ghj9O6;!y5hA%-v10f=Jo1b8%i%9t1ZlU zX-f9n^JnD0UK8ED#_gsroSHQUYA^FUc;fC&uikXQ?$_OR^uG1Vvk3Sh6kK7bH6#cc-1QMX<>3#Sl*@-Dd*=O9(FU{yu)eI z+b2D4U)DP2*MA;r$kQF$Gw!>l{r7IDe&h6!DPQI!&G>x6FB?ADoTu&lPe%4@$^Tls z`|1j*`MINEZ+1rSII{4whr8w%w|>0+KPNx^WaY7<*wcqf!V{_s{?^fy^?CUWm$-jV z88v5xcJzzyZSeUr@+Mc^i_y-P`1yJ5zfm%RZC(n33bji!o=vSX|za{RW zG5rUg^SG<Qz!OsiQT^^@Zgq)tiI3z3zjuM|E1gRYZuLZ zE%Ec|K3&>LqhI-L;i$P;>s_M%ej@A0k|PE6C$^N#TDQL_Ve_u+4<_D`-&}W~bn4ur zg=r73^===v!0XL70-P_pe46W${qy$zBgAXpYY#4OobIx6SLO?6K6_`@M;*KGedo9DJ`=lXuXsldH#{4&Y)_Jwaf?7zP0=*!bz zy*Xmi>)uanIq;y*{)7MCbE130g-5>d>OAntoiRr{e;U~JWnsx3pI`7{!2a8=pZ3OY zU#)E@UAtgU&^OCHs!c1$oOyqqTYjdO)7Udl<=tQOa?ZdfXI5p$e`E}(JUY7W#{)i} z>F;n!d1u$CtFosRyzqNKR!8!JqNFd@mRz%N<;O2~FaPvVzSohc{&`(jroY_$*MB_q z=HXjEdTqh6GrPkk|GaPCJ@4#&KkT7h>CZpc806VQ5=B04RT8lT}RtL zq!@H3)tfd_WJ$E1d)!9rZTO6q4_*jAx?mR=aR|p9px@_ScG+)${Vwpk7EyWQ7gRnD z)OX{!1PuPtKKt5xsXgtFl<%*j@&IJR3A6(k-cNB`zuLa&d#Y-D-xzWfenQRyRsc^g zq4j2X+WtPM<)FI04#@oZi00L>6G^cj*mDi+wo!fqaB~#Cw-nU7^;3-7r$g6Q4SNI8 zRBnv5U0+B%)tkN@+MXd5=S|K~G)i>e?~QUB5Dz;MZ)`kS8tM1Nb?5l~J<~UEf z`p~aje^(WZtbb~pXumW&+wPx?+lTHS*6!i@XSnv*+duy+d!p-h&eopjIvacKvFi=~ zSM6ojt2oLYZ>RZOuZJ1tdOLgLyJ-}SYsuAie1~qd9p9q$e&ZdK?|qn-&(fkE$eJS* ztAYK%3>+s}60P^aUr{|!*%>wVQ%_SxHbRBf-~sBL>a(2LfU>aW%H+1vlYZnWQx z?za2C^3IXqpL%Ke_GBu%{F}-~U?(v08?@(}v-7{kgZka&Y1@Bo^~n6+ei!BY zqo4IDRBnMBa*SdPZ~&O~-P!qndNlPr#M`$2ntMj(f92hjU;8~R-wprcj#GIj(EkV2 z1MK}l?f*#E1JQAjUtfCdv}f;nI^bY?>^eF}*|WF*MAt#uYmXf-{#X7rpQC@G{^O4$ z_S)9tX9TpC2y2IL2NGXXjk)@piPoIM$xY!S=SE zqrIjP_Fp$w-*Em7XKy(Fq?3-d7wlkriDzlgc+$2#NA+Kgz^}8lC-SfHuff6gIvs3pz`^z=|K?bGQ4Y3eaIn2<2ie>C zn_A}Wb^JCmdybmFCpo{))n3r=jzdP1myMyiZJJ_E8z`5Cr z7_e=3r1mlecFxuw!zu^)$8fuY?eTWn&T%|=d&kewp5H0^+8ch#K700#Z-#^I+1uU? zcDC1Edvy-B*Xm$pQC@gy-Ek$+h(V|mOt#X=ji_HwbMU) z?eTUz{^MACp$@jEbFjS%2ivQ4u)Ssn+v{<#J(tstwHM-Gds+wEGdbAa*0Z$NblSE( zN3RFnXX&5Fp7dYG+6#8Dy+jAwGdkE_jf3qqI@n&9gYBJmuszM6w(Z6Jd3N^Bb-oq; z=~#Q49c+)c(;(=-v$fahV0!}&wm12VW9>x=>>19Sojpg7Z?%KlyVJq;Iyifx>)je% z>GeqLdbc{r{Pk}2X;jaW$ezYcZO_lmw!PML`|MS7_BIIY>6h4NPjXk=>lN4wTBf!q zy567N7kA(}dj0;!cPX}SS6}a62wpFEP21Ji`wwTo2IbgwW$eCA%szkJ*>LuH_ECFn zpZMCe*E*W=`k(h5(q5|<)kj@Ge_z(O-?qIF@I=>3wsF5tu=jdBd#_jD7G~dg*5pxr z)qS)beRohaY*deD$Slh1yu#aNds?qh*Jpstw};*DHwxGb-sHIyGZC-C`xpSjBPjCs zd&;^J{e*n}eov7fQ-5lK-Ukq`z#d@aClqxiTF$#n-98iQ;qUik>Oj8$O%v!iHI~B; z#PP+cBCSaUA{m14Z2l_|s3Z8+N09 zqH^cY=&uTjn-eJVMo;xd4y7&jNj>Om_cRJOk7`@NXthpwp~xyVs-y+ z)7h?%pARST`)BeKyszcr^iaXh&6^ZM*%; zsopPB(7p`Yb`954Wb>yHcGx_Uu2=WpaODD zPJzAcFRAUF&a!P!^!un5{9dRP<=F3|G+0L*WpC$O6zy$q1#2JIUgL-A_S$>Au=n>n zCj2f)czu82+0}3F?<*?L(!RaFA81)Qbo+Fx&aQrYum6u)HFW(M#` zfz`lfU?c1Y-AesvyG7j}jy@jM-b^tliDFnO@NJ5Njz=|We>S(+_Q!mm*!N)P1&ZAd zU>sqmZW~39Cn-*T2;=duq5UvEO!XtJzv@wnE|0(;AnTWwTKnn`ed6ru-;8#)K4H84 zoln_UfABMBSAXPl6q`}L_E~lNH*UAD{yx^85!SE&E5)t`idFUM`YT?vul}B$XIFpq z%M>gBhWzI#HUR5iv9JEfU1wK+ZzIJ{me18My{@jmxrrjbPVR($8)SZc?A=GP`wfcT zd!gS0``mhG-WPzM0lO~y!GpX3c5A>h>{a_K>MsrSBkixvf2Y`n@^$Y}^nkvj)xP>0 z+Rm>2f%hp^La&F+;x)3}zWT#HI=lL{|3v#yetQQ+3HrE?)%AaseHLw}j=11`~Fk&qF6W9Pe4%Ci=9bhX^8c#72 zSP5(d_5(xxDHa0Ryl8{$G68-7jlgV18#)g}xcwru|6+qwZf52K)T_7ZgGLZ^HRskJ%JY;{29B{MQ_{ z-H!gR(2k?F{dd&;5+c8{?SC`;@A?<^1Moi+SPg6h_5i)-P>cW;0=EJEuA+9^Sw8CV z@3q|zC%^Vq`RmeayFVOt|AMHmZTCmmWXh`o)&o0$1Hj-Z6t|sEQ44tka3`=E=nY;Z z&w)?m98+HF~|HgLzI_mxk{r|Szzup?k z3kPNbHv$`g-9YaP!3SmnoBM3Ha~t$K`)s$*QTJcy`_^{*s^MP)unQQ1^E8#fHefgW z5}p5y!1p8dRWv^X@m~RC-#>-^N#()MIiUAeq)&yA@7rB2ttJdTcb|H82mTcE9lh0Q zi6lSg;U-d+-Z9)@b$5Kry}@nW(_bTn;11(5uSmI1x#bS~^8Lh1l{=VUs@y@J-d~*F zr=H$3lBRMS_l2ZS*q|v_xih5PvJ%pU)ylmhmfe}L>`emW#lYRDM*uMNNbe)%hQpS?`Tgw&4X7G+EaqDDUmGCkf6FU zQZ^Uk$nF=PtuTyAE9DViE72!PXh?19CrPk7-qWPMzkRGUo&3=#S%+v^LPlLLvBaJW zE7!k(NR}R>X_;bOzDp?^K{}!_xQjg<@au0vG|I|6T&}PF5iyS)6CdGOM z?t#km(Ncl(1O@pHsM%I|a!Mlk@?2X5Esck0Nq$a4i85QMAEkK4Ln6viUb zfJ5_XzgbE#y>&lCDUInl?@3DZSe~|Hv1w36)eJJC>m~XOngXfB-0s*xWtN%CXh|H!;y$s|pE$zFA^sF7 zJtePiEU|S-jnwftPp;w=`X9`({~zOYtm^Vu?M0$NJesa!MhR_2{#-TB1+I&?w_TSL0$uqE9YiPdlOUFF*C7 z#H!WQZW`BS+75Y^E>gvZsGi#z%&&puQnlHD*h*6eXI@0okpGu_8AN*7zxt~mm=Vc^*OO>cHShZ48X5!i* z@@=dGw)rN@dSnm=V^w&Y24{Zp@K>6mxf<`s$AFHqhuQ9Q^~;>c3g zvfEJiHGBF&6B@CLOG{s8l=TWKa)thHrx-$FZ zo~6AVt<2PH5@!})SkzgM2d|4Y9|P%AVCej@l+Y@c*pr+FbB6cNRy%AzW5`x~($*9y zwdM|*Gt7>q6)f4yOIJqRWR4X2G@V%Ge|g53%&{cL1Sm($oRhijk%F!xY8ApRn%XIzH;J7fo9F0RB8 zk?B_}D`%=yrp%ZUSfwJD+ z%h$l?^EC|4SJx1)^hpKjH#s*JT-k;^w(&}D(UprGpR$z^mdB&OY8-Vq0@IyMv01Mr zwsMr2P(~ui(sR+I)wz=8n7jnzLe~!K^?;^W^So2*mnsoYkNrj)ahk5I7?yR@`nhy+ z;vlPeAruiubFo-4eL^ve>=uA&bLb{BFzSg!LI-P5RUaw(4eQ zJf3@AMO}45^71?5Uar5n=B6o6Z@B%7%l>|{d{WHA2e+F_j@+<+Lmahd1V#ci(KufX zSqtw0>v=YX8_g$+kyQ+f0T~^29rJvBkTN3WzNXs zo~^7t^5>rUyH!Y@+2qpjbw@qy>&t~?yG<@hb9e);w3Ijld1dtP{$ z5%WC<^V!blg|qTqD6cObS^4nmDZjA<<#I<>p4DHA=an~~rT?1BbE|*rx^pYvwVq;= zp!^EuY}pElKKGP9!*jNx7v<1oD_0Vhv!vntWzUzNTx8qdb6YQL`#p!qbT1&6SfQLx zU17DG61QvklA=KM8n+a>JrO6|``OAKAlV1Mjm+T(@X;^F(nc8Q^SacFy#F??J^$PS35 zKtD+uPhL^pk~EgQ#(B$^E|GPByd<(BoF*?n^8P&Xnn+%gylJ^aCrMgJUW>>piM&$D zD}}tYMExv+uO;NQl)RR~7Cl-@IGRd0+DbSY zOE_9f*e6I>y(Apnr9tZ!OXBs6Cd>C??93lc^m)w{DHh zk?}L~M#lHZ9~pn+2>C$;BjZ;J_|>0KdFv-?{^V7Zp9wo*c#f)wpD{wdCT(Q=%n|Y{ z1^%%9Y3Ad9)zJOP^Q-^#8Im6y;HBbkNE_OI8|;UteKJxA5 zo6h(Q$*<=6XYyRz{={`sd1t4Z?|miZAOFlg`yN-@w%-i9{s-0kt&x;p#kF4pUKGc# znm_dT^7fmD>HnTCH9zyZq4~!-e(f;*&#x!d($MyU4ypO!KDPNR887rz=|#A0D&=XD zC`K)$xES#8IZg8Wp9?Fb zvh6kIDetG2oAuX+RZcbBAis}F(kd5XmFBD*v`;?Q=b;WfN##1+XM=wps>puG1C-bO zIK`|dD4x7mZ9nrV`|Ppb>r~!F`J(%O^gm&ry^zs#zPsFw^6-PdKTO1vBeU22H2U#J ziZwgb_O{w-kF~ddnD%biW}iJa-XV9X$NTi1YI_pyXTv}LmXE9I<1}vB=P&kotP16s z%;K6Q!@t$*s0er3$@^cU|CeY7aOan5zXrZMJ3r$N({dq4C{_Slj;QT<_o(H*uc^Ep z`s%MJb^?t@DK-JOfnR+LJYah-#US+aw(lwGzE{_m(TDng{lG}r89;f>cc>re0y|Ai zh95d$B>e40KWN}@2HI5x|7yNb`@^ss`jBraRsdUo-hJwFHK?Z__QPR64t7`)&7b2h zV?JC$=Xu0im_Pf~^G7ey{GH$pH^1$@e-umh+N*ur*QUL=KkQpC*m`Do1?$02w%5l_ z*sDjq!`bT@#$MQeMrJRuf$}2%L9y~hwY{zX8CiQPUme7Xb9Ps!T z)Qx!x#_FUfT%mHKDvmk8OK~Q6sbGjra&VYCB#so$Rxh=tp^4 z9OqiTrf7PL^KXRh-3Wi`zO@~HlFP{KwZfkFced?yx{l0V=5cB#^atDaBHTu1?=8X~Z#pFA>q%)jbR z+xD7Z&%1tTdu)AZ28z~)$#$;Sr^i#C2gW_?8)_%wTeZDj*sHq|d^^u~u=b1YugL6= zbid8+AF@4#`orHpq+y=A{i5ql;vy+8;~KQinCXkWS_l|g_P%w_^Mn$F^jX;4tpWWRpj!O*q17HHBy*V zDNQwh6R#of^MMAd>ufaAMMP6h{-=rl8qRV(dpVIyt-k*+!ZpS6br|&hT;-aL)ymc0 zmaD-v;O9&97a**>L6Wb}XTP>1`_y)c_6xA*eTtQktATYu=>v)_ki#JNK<;M~ zHNY^S4wwZr0X<-^3UV#53E0DU|AIYW2G9ho0@eWQfla`!pPUqoRDRjVuJXP{Vrh*e z|Dwop9r#-F$gEKMQr*{Jc5B&qkD{NGV2&mEz2v$iGmLud!iiaCvov7$y3P zRxw}Au*6XWC(k00Wi8J!Unj`&XIovjGq@hL<)QLvO~c!nV|6{^P`tTT*EtPcucZZ% z68(KH`<>7_j6kGBf5XpWW2qD^rAbNT{}f4&a`cyj@{Fo9k6R=eIr(=YOpcM#2|vy3 z*Y#x9%fCvIzhJmQk!jK>9;<)ZLG^1S^)ELV-|`D9DqjYirl9U4%rl?~SOv8HWtN;Q zzh$RM_Qv}6NOJG2w)(w_+?#_v)|m4x-cg;rI)+I6?~Em@Z)7BCtjpP>6G_faG@T8) zkmTw@)7hYOt_dO1kgYyWISKU60{tj~-esI^z3UX)dN)todUt`|Lr|}$KtEcb_Y&y6 z1^)X8{Pz|3IR<+FT(#a$Q14iQew;u*UZD3E_&-75e}KUMK!H9;Q15vH{X~I&l0ZLM z;QthX|K|(*yg;DW2lV+8tGfj&;4j~D0@1o{O6eWF00B+xGu=obm}T7f=UpidF# zQw4e*r^n^q(qe%=O`uN~==B2q5`liHK)+0&&k*RZ6X=%<^w$gYnF9R{0{x8w{R)9T zi_@P$Mz%noBbcYT0=)rt`1zP8(C0(1J{?A-4{kp|{$(dLx zue#ng-zbRNVu8Lypf45ZO@j69CV{?8pf4BbD+K!00{t3+eyu=XDbTMI=+_JMHw*L| z1o~S9`o9SDw+i%C+_;auoyxay@iX>LD&Nl8Vf;G;b~Xy;#U_FNPJ#X|fxcRxznjyK zh5jA^|6WcX2>oUO|2~0!i$H(BKwl%67Y_*Z4+``T3G`b9`iBMjM+Evu1^QZn{xO06 z@yl)NpAhi33G`12^iK)&PYd*QQ~Ye|pAqPv73iN6=(h{%-67CFFVMdr(ANv*^r)ClB@T3U^}ND5ZE~- z(ElOO|3{!dEztj0p#M`4=VyQ#gIYgq64-Ot_XC1)b`|K|1aayv;Cl%8o&x=7fgLXa z-&?@<5$Jsd`Y{5%pFlrWpdTmDj~D3u1^NjBeSkn8D9{H9^ydlm69xK70{vuxeu_YU zzCeG0K>t7gen3#~RDph)K!1rqA0p6SD$rjh&`%fWLk0R70{u*Z{&ImnOfc_e3G}lC z`Z)r<@cRLQey+gJD+T%pf&MCi{%V1KouMz0473iY`aT_hr#|ZSX0)3o7 zA1}}+2=ogC`b2>~NuXaS&@U3`wE}&zK%XMerwa5s!MH3I=+gxHbb($k&@U0_mkRXD z1o{kt{yKqvxj=utK%Xhl-yqQ6DA2DE=(7alk}cqm`1=8YK2M;}7w8KF`a*%eNT6RS z(618cje>qC7U)X^c1i_$lfceRg7XAr0)4qaUm>V>wLrf{pcj5WAn<>kK)+s~zgeK) zAkg0;(Eml?|E&UjmEd#aZ36x60{tBV{YHU)lR$r`K!2A&UoFtzEzsX1(BCW2Zx-n9 z6X>@H^!E$&HG*+@K%jq6pnpi9-zv~QEYLq9&_62B*9!EH3G|N(^iK%%+XVV21^TB1 z`lki@I>EetMxcLIpnpzaf4g8^+9BXSFPPUa2=v152L$>T1^Sl+{_GU^|2F~uWr6+` zfxbbYe^sD=O`zW;&^HS7y9N5!1^PV#eUo5Z-Vo^b3i|U+f&FHIexE?UU!Z?Wpl=cA z-xlcK5wz>?0)4AM{||xwp91~60)N^B@%)}Z|Gq%~fk59b&S==sN`Mb=da< z0{aIA{NcVI;PoT^en4QyVc!o3> z(0?be^Syw7T%i9!p#M=||Ac_wFW~e@xRj)>643c%Sy{j^DAD~=*mh9%Cd_!aoHq0yF5>t6*e<0 zZ04+4vuDkgMiXxPbXw*NN%G}(>>53m&Txs>F_|kSS?AfZ;Y?og4=Ln^dy&@|^77$q zM3vEgsRVi~^iyHi8mjNb_bbOCw=5Z}pze0ci@a})O>C&7*aqwYN>9*oTOU`KHzB_Y zIPe0^?|GKuhC3;4guVv6I-nN$nZWRSDaK}(l$2IzvU79u%F8u#X3xkes?b!dGv#Sa zrKLvA+McdF5zo=b27KLh}NU|8SPj_aRboLNHL-uJjmKD6oc+Ze?Nxy z{(|xi)K3HWnW(1^cA8LM)o#i=zLLs`sCP3^3wuoug5L(Y9{!?ycny`;R!UMn`7h)S z`g_glO%%7@NwM-)iZ108w*&iu8AghligECtV%V(NbHcBfdu7B`**Up}ynKHC)HTui z*?qV8{LP=BeYoG@c3|RBiebn%9H6Lwmty@9iW?z^A5-_kKp(|zz>e=IR=_Tc`$*KM z2l^pDeMNlA(im-O>>^2`a%^g{E=e0dhskkC>9Nsiaq)4G6VjrS<6~1(7bV40ezaDb zo}`aYN=Zmn>}BXu)65SjmF*=YEJ#aTqJx|sAFEGFO)=-k#S@Du3*u*UGRr5vMQfFE zy4cjXcyqaEy*_P4a&*ddY4HopGI^gCua&Ijq;!3J8j}_0Wk$MOG&VIQT_2sISNM98 zrAyT&rNpCNLeQn9#AL7x)K98I>t-|A+&Xo>Sx(ocvW{nb+Iq<5*0c7=J~6(QlXcOAZMKMUu#y+Z z4M>Wf8_x1M*~)o|#(@%7W?3npoTN*)E^j3-&?lzFN5{=!aiQg8+8J}y_L#`*S;@L3 zF+?Ifxsld9PL9!8nYFaTEXStCq-vMM>6I~y(_87y!6d;y*7>xa=oppVWl8!(vnbaq zPeQAFed3Z7YdJM$p&TJ**%B`+()H9&{dGDPQL6Zn3FdOcTZVe%YKp3TX#AhUVN>@DDA%RHofa~z|+<~W9Ij$@Y3 z$?8tD#4(eVPB1SFR&i}@&q_AOHOuE@7T3)F(gb~U3|Wt7Tia*Z%)XVZ#JPDy%<*pF zb28%Hdc0XMpuIHSnLp;Y63eG?Zy8_fU?FiEpKS4ygr|9&v`Gt6B=fpx@!y)J>d#qo zD^&eS<#e)STh9|q|ANoS=KhsM>;6T4YTr9D=%(jF^W%gLlY zL_#~Pd7P}Y!%B`%(WhOfPfTL#e_FhLNgCTGNS3%{?Ka0H#xb6(GHDAee5{w2I9`gC zguG8*l%zu$Ge12&J~}Nn(JY%yLpH}b>NCeVWULF|YZF!^$0x_cr;)x-O1MszQ{vP0 zWQC58&!G8CRtyk1H6=bdUZ0p6XH_k=W2GeW(u5@`@}`QFQ)DvcOitI+nwe}RDdiK= zl1RG~VpF(!s6JMk&gqku#>8r))6>oMS&6c2Eh_w!xcCfagUE47$xEZtv`bidDlajY zCo<_l3Zp6P=b8eI4^R#v&>CO5lcB^hgCSxezmx*)JxYHv&_~R>HlQn&(E+Mw6ODy zBbD7a*<%=aq9A|t2<`Cvi#VC(dk<5NmuGXbKPR*H^ZpFiPa~Cwvp;!+{Lpi>H=O;E z=JVs?44I)DhisgD?bP%6ynSBJ^T%=d_WH-l1#o=6oJba-ivU@_ieyKj$Pa%04yR|x zx0~_#dKizz%W(a}_`E%yH=HbL|48lGi}v=n6a5*l)HH$KuaA8P)fPl$mNqP*=kJ}t zuLs{%Qm1VO%B#A8;;0E!Ukg6-ql2@bc_Y400KXc1M(W}C8t`4gujKdx0=^sgg^0JNQ|g|3MtT1^m(A>p1%%96w?O?yCuY)C6@tpK4*>1N|Sy`4h(3Z`4!1C-@rh z*|kwr+RWX@3l` z%}%}t#;eI+-Tx-epFWJ251TLkw&zPf<_k-nY`zTR4~sXppQyIe|1t2V3VgP{RSCvx zEclfized1!V)JVle^~!a06$|Gz8~fbJ0R+~c&HQk1AY|ee?762K-M1e>C{@0{#Z@Gr;#o|JRNmx<8HJyI_J=11}U1O6EJ)5q}>1^$c$zl-DR zIKD>~#tZzmaYM)32JrpZ@rARWA@GNNE~p#EeiQ7E!Umvb7=9b$v*X1$b-eNWx6|Oe zfNuhyk@)>vST^Omf}h3l`TZN?yMeFc`iI}YF@M~_kK+92_iqN+_hb7j&OX0?+m?g) zLA+^(>CXz-_lA8x&L4jNz{bm$?XQNh&-{1Bde}c!?LU7!V*ZbU|2-U^pYI#lc!A%+ z@%i~)2>Wi}w{U!ZzBBvo;5Tr5em*k32l#aypPw&`?*)Dh#~00CAGV%z{GLg+?fZhC z#qs+Dd~^LAKa2B+?QdDUM1jvA?@nX?uod>1k+8Aqcq`=WhhRNnpAR(PGg2kT56Aej z`aL*)jeyVgQv-hL_SOsH#~pH?pW6Qhj?d-``<&jv@mn~49ouiP^5C=fcX0fj;Cn%? z=lt*I_$;yODr-6Z0PjESv-`GHbN)+Q{IL1U&JR`k*^UQ(KRF&)=x5tsmRNt{a3p1b z&&JPhlAt^sPUPCF5%8VBkKpWwaQs&Ek1O~g96v(9cV_!-&Ywh%zZ3oG!a97I{$a@- z{Jt@^`+qyP-*yAPYmC|-9p?|5?;hZ{ar_L9-^t<`{3ec{#qm$G{WJLW0{{Eqf5=kA zKifYG_}EdJR9tmOD6j^B*&ast0_jC#IQa{ONKox#uG_|*cw z7x+<}KeYn?*&XUbIDVZV-rT?s;`sF(pRLdC;CpcV2EqC;8vFrYHNQ#VzYq9*9KVI* zv;DRQ_+1>oP2i6=_$?g2gX3qi{Xh5(9KTD@pX0D#)p30Oc+K|Dm`#bR2@yU{CiKqaY&x~eq_FZmZ^;5nMe0IFjfzQ@MmKZ+^d^TUB?DU`6 z3%8Tcj@O|AKA%{BXzb*(DFOFXWzBBkW0=^T+9|eB(F#I|e&)`>rKSkmb zB{Z;j2ES0icjEYN;Aeo(?t5$DtCKqviQu#SmMD3EA7STsd4eATK8tUb2E{WJK?3_c z-wO&4A)l^LEi9hFAMhSJ9=gD13tZnY{5}?MZ2#k}or7krOl;(_tUfIr}6Uw^U# zb|3hbCvCAr?dxElS?v<=oj5)_z_)S!)Mu*qBP_A~aFd;UwjXY=v%T#6VV%G}pV)r5 zR%oAkl*Rf7=ew%G7p*6?;Ir?eD>?h!nd<#gJ^1W=W+C{4_Yaic1U@^TnPDfNozG0< z{9)&NnE!2TeE>hgYv_3H0-v4F3<00*4|skb`0V@QAOYWrgw#sBD`=Sv3oK`j355Dg9`J|zJnjsB2l&J7hev_m;$dI^xPaf_VPAZ@f?o&zaQk65@N2*yZhztqeii4B zXn*1Xeuc0<)%y)k@C)taj|M-3^GCEl@d7^){NeT|-rz@gh~~R`zu^OZh=9-UPkh1G z2>I$X27Ev8hufd{u`gf*e13m27W{tqq1(&$8{^n~8HUgH598T<5%Br_hCiDx;19Ro zn84NExXFyZ*B)A=m^!5{8;bODQh@P|9zX;}Q*Y5zhN|8DB>6&>#`V(}0D zaO?TSEdDwBqT^jKi+}KkJAO@N@$Y6||4(D_Zzul}7XJc1pF&vt+iCw&7XNngFJtlV zCYmqmG@Zr2fX}B;7XRFMiP8)f{~TX*e4NSR-%S*slwXMXcsYxIH&OgkekJ%}EdGV@ zN%_^_&tmcKs`j5>-)h01&ElWqi_#qMyTHF_5Ci=K`{CfX*=hd@@SE)9&jr8U)xP!N zO7Lr4?OT5$z^?{>@b?$$bQSoOLjSSB2S372zPzB7 zl}m$ucXzqAsAN@ANq#ALUzRJs@}<(%6;dVgjkuo@yRQ;U?EY097f>vmLoq9yV&*jz ztH3)RPq7>PPz}ZK%P4LSqxLIiQ@K5uq8`ZZqvQ`>{pD2eKZ{~z7{w6ehtC|V?w9}4 z`z@LM{)i&GACze#Ef)e__?1*{gB;|H`)QrQ{h&P6{lcTZ1osW|!F|R4q~+?8VHf(~ ziQ{bIaUV60*{xcMe)6SQS3t4yG_~LU2kvVXP4%6?tw|KO0~=tswS)FU+hQuS{^+@c z%Ev<}>L53u9dYOfJuve|n%@OKGSFWqQD4?1iXG5vQYbbef3u!q-&oWOJ0>qGyNsjA z5{rjwln;lT3EU2BV{rrYUPRHjNNvxEe%zQxu@G1X>;q=zqn$t_a0AdAb}GQ<=bP92 zvz(N@vL9X&{q3Q=-xyV8k$JSXb9qU2abCHkO0_Rze1M^^P|N^U0vmztz;5tsU$O14 zIl0i!tY;LKld`_b-g!uLrIf#aRF)(U`dRplJLS26=K`K9xN_U&J@Fa&hcs36>%cR& zQjYwRWz_&V({l9r!hYDF`3>f){Pe?dzy?p{=MeU+{Un03fM>pcqbBz9*y+TJ6oteY?rr!y%Nqv zYq9(NCs&%T*pYkexrYr;&945!cY9O!y7P}6?5RF<;L+*Y*FE=bc=a#tGn&4AV9HxH z2ERR1e%3UsOuXrhUk*p_-*`*s=M%s0{jzxR?#`3%Zu;borM1TKE%mDm>rdtU_xO8x z_oQYz`5!X6<>t;G^T)3~9{06rO6J|@SETKY&N^6jQ^B(z_l}BO(CM=1zngpxtlB+# z#~<~(uQ1lW7W3(QZ+;PVs(I(v#;)0`Gmpf7X;({!7gsI*tSunB zv6?o@#Oq@u+rP@!BEpe+D1(diAairI(M@7G}IOCHw99 zGxA@riSAzGcGDM5&6)$Xm-!t$ardTIZ@OUj>ux)G-+FpZXH(y^@3~iopOVIGsrP&& zsMhzZH+@##I%9sZ$D>BW15TN_-<({$YE@3QadKB!-lh~O=jR_Db~E0*!)emnCp~Uo z);i|be;#Vc(;eG0?z^V__im_uI$j( zxuaokc1G_wvhcHqyXF_Se!TrZCqMmU<*}mJ(}zmJ6RHdT*3p#pdHD>NxPMO>HD`r( z^o#Fp@cAv8X+uaA2Cz^fHkEjakyD{But zIbqrtE_VcUmyh$x{d(g(!`5q77W>pMU%B4vBj4U9&v-s`$;;B{SD$jfCGMdy{Rf`& zxU2AIr}O`O$F1mwWjVipP>@%3(_G_u-@2_TSu?5g&z|X@+`WAL=YH)Azbq&{^2VuC zC-!fN-M=UB;FgB0zUMyu^e+#6{7maRT@h(NA4&bG;LVQ0E zUD`>bU-@m}sJU6|U84VfBJ0SKBL(#*wv^0Tx4$T1^RDafED+X%DaU zZXdP4>&-U;oG-e3n(LDN^Y;ED#B1Mc4=!(QLyEmk(dx z@Q&e$X+P&4-}cOCVzrN|{%hO-IIbzc5 z-cM{f@SxBBga6)hqI<)IN51gtJn+e#F-JRp8rbz^VaXkzU+`hT{@bpf_Qr2tt!*e> zyI@byH_JV$O)JNod4HZ;ex{ex*fUS%-Cy)_&cG*UR%OS3WDKZ0I=b%113sVW?{Gw<@9cd)?4e!h&p+1~>^iq&??Y~%eR%1z!}_-h4qZHReg3Ydh1spn zlL~LxI=%F=EBAXfKC{L9?~{(WF2C=D^Ne(9om4JWNO@ARlqQvuzY1kd;E&(cyXfbG zLZIn7igNj4DTkCZlJ|L1wp1qNN`;b+ysIF{r*y*1Cpl{sW}cKOB}+x5L>bYSBQH~0 zN_6GYYQmANR*-iFqA69_>BM%N6vOPTE6yo3rstKd$tz3Gt4K9f6qS~gtM#y)x- z#P&>5UMtaCvP@lDPX5`>zl`LUTeYv8)X$Q2|ICb$@2)IK)2ABDrzfJ4w0a_knEBW@ zhU0TfM+n8>OUJ6#?cM~n%*wTI_f_!pG@7rygyL|YpO_uLbhRw{{1k%EP3-d%JB~2q z}_U;`hv`JNeZ=*6f`+I&+7!{=B$5d}_i9 z@7^;0zy+^8vFL*Cge{|X-u%NQVU3qeEx+VK`9ET7s$r^mH>wFKEi)9AWE)A3B3ns( zd$(s(JY7vOY$?T_6BIWuqu2?)xcWP<)C_{G}&ApC8m zSYDPZnG88n*u%(2yA8LZJg^o1w-7$MRA-n`$$=giHWw0s!b z2Xe^xJZ{DQip48S?FYx&Wj|^H#SYkM1&{69wgU?fj8)mMJ#3$Sh8|rs|2TM6u*>{E z$=Np?9jmg->hTw~1NL3G{t)#Kv(Nj_>{oI1WE{57e$xuN-ka}N0GWMXdG*zit4rk1 zlZF`;*#*}SdBqASl>E!d>M0)?E+@wX`6yu^|Cf<<)ks#>TxpfWl7*K~R(vC2l}qv? zl==H#hun?x2aC~9e^P%llc`*JhRWL@Yf`c9X~(H}18EeS(_<~0@i?)~tE)vYVuj&5weG^$2-&nW&lwByvNLsvxJ zqJ8+)SC$Msc47>FT)O|}L%VkV?Y*SUE_=#oak8*Pd>x`?0Z( zKW>RWSBF3rt!s|L`T$x_EwBqX8SCBvNTpM`XXHfK; zMsX{6{JNEia)m%qKZOU`wi|i{a4toUD=F$xt|HL3-P4d+>Ypg^`#g%8NfhfLS6xF< zbUsyd9Eb#J*?J7Sg%fT2*@JwMf2Ip5P6pOuewh|f?0`PhkD|+1iXMrulSFYRFf>Z- zpUHn{|4v>@u{+qde{s+s2l8>I54LSLbRk8}G~0IBI^;bS^<&(_kY7F3w%tnD-F^wh z-kB6zFH!q@@)FzrHbT#zSBjcL^%=}AcV4Lz`nHgv>lO7=SIE%yZeVt~dOfbD`ab0A zFM}OHe;SY{{h>6=mdom{ciE#W$QRzmV*0%L$ecj)psXAg6d~1)GJZH;m+q=?j_kt!5co^swMo4hkw)nBBPkaNn& zdlUJ~Q_9F^Ry1T^y$1I3rBbCnxl{qsvE4THyh72GN~?)vfM04K@<_Y$h`rT{4>>4n z@t!5?_9iK3RpO-uQZ&I8l3u!w*>wGOKmyCK@vh+i_)tNC3M!bYb^0_NnTE#^}89vv@Jtg-j z9T8jou#|YqBwP6@#BaUQU&%x#_gJ#hcD*@D)cjP^LcM|s=nZwgPKh+RH)MM>?iQ0W zNy*ORASIMX;p`S;cArBN&c@*R>$S#nZAiF}Yh3p2o60$oddq7Tv z>l~fL7{RMdAX$E=8?<`j>%aZjg zQ#tD@Ni&t#%prJFm58vdpDLAeFN@L6;E55ZP3J)mgE-| ztS-xzzeJ$+^@U}`wkExzv@E-TluS3}GcWkt%j4di{!>H_#9e-)rf%QKed zQX}bkxvR^HD%dh7#aHI$nP8sP9$(44Amd(IUR0@xU6KU;vZ4}0>DqF$hRF+voI#Fpli%BRCfUlirazGau^k}i{y zqtnfSo7WkFHVl`czp<`XK{P*^}#tjo0C3|H(<|a#u+SIx=%o@yHN){RV z#3jk{E+sm7j`CnH5=T;c;uYi-PF`~q;{@ZU# za^=ey<@ijD*XlH>t1C36`IdN$SDY#;q3%%E+DGSC(rK@8zqNX5_Cn8qG_Gk~A7;<+vLJ^Z*WAK(PI#4mlCkDEV$7uC6XF?(TBFtBX5(9K;znH+m-@KbD;R zT>T|~C$gcZe}wMuJYG`C8UEL)MBieb+%kqKiXsHzd%D^o_~H|0rSh({5MA9>lauUP&C*l|CN^a zzN6`%S>dd{1)Q%l_vfPi3p556ySTYX{w4mUfu_KlB==FuO_qElZ)g9qaZ+G;U`62S zz%~AB{VU~r6$Y*gTpxII;D*3k0{;?tYhV>?2dP*2bMkce^uO2B{4)X8FLDap9C)9# zZ-H9^?{_76ZgRgVobghiOQ5UV591|ELJnzTpjUu*fKPyLfM3AafN=ri111Cpuo~!} zZy5WN-;b990t12q&I_0rFezYiz?6XVnN9x-{59&5@Y8STzkmw^E(*9fAUI%Zz_fr% z0zv{V4Y({|dO&EvjDVQ|mj{Fi%gqXyP5z$~5FU6%;M~9~p_gb|iJw;o%nOJNnD5~^ z^xts)xzami`H=`5BnMstmPUDLl=q&bXJgbh0<|P>oHQ;VInew(B$fiwEWChpu^&pl zK48fp-BOjbOr6X3|9EMF+XQz>Gr@!AP4JY+sF4rU%AX~&NYcpvsYcSGr+dvXAk&*I zaD1C_VJl9~CIA1=f2?J6OswBi>0I-zwfx_NF%pYkJ`dwJp1%CluL=Hg898s5avJ() z-B$Grf987lKaNjq1jrxiNvtU^6;s_OL%)Xl8!q2gzoXnZ`lsk;TVA&1fd7xZcY&|! zsuIRe64HjWnDha~`a0F5Oogao+J09O)9W=bVDxi`rzH@Ua>0in_wOsLQc zGij~LXsxJK@%0VPbd+|g23v*t8tUiw*%`+fs#VW5KF~UfGi~!ecQn7`(#2Zp(VKeHb_kEkf|vl&yZ;>*Ps(cjwnmi)Vj{$3X4lKA1ys|~IN ztLzesEP#t=`6u+h;$knJSIqb0g3&m{|w@KV) zaYN#U#T^tkCGM!W`^23P_mH@U#XTbKQE`un`wJ=Gr1(#YdrI7A#62ypBkmb-&x&ik zOUfs1t+)%twZ&}^w^7_Caht^ri5nKTTihOT2gMx`cb~Y2#62wT5pj=-draI(aZif- zjJRhM{bNF}xFK=F;&zMMBkrKMDRD={9Tm4(+(vQti8~?gVR0RC&xm_gTx(qD61P^| zh2q-cHi)}O+(vPii`yjbN^zUTZ4);nZil#Gal6Fr7I#qG5phSwoe=l1xJShOthh(T zofP+!xZe}^8F3wP&x&j9m2!(~i`yvf3#vTg4~g3??x46M;_egokhn+0Jtpo+aZiie za}T>IaYx0S5cjaSN5!2K_msG&#dX9zD{j@h*S~! z2B*eTIhs=MizE`g0IKryryGi7wqxSPk^07_kwucy-Vu-3L|SavvZC>fK}WqwhJHFW zhVA}zWGH6mhIht?qb}egwJ<;v{yH!n%jVL1U7Jkz#q849RJNO9L&+Vns13!# zC4#=#;#hAAkPhH6qiQ$aA7}R^hqICRFqXZ({f6Zuf^b8!BxuG2Y>7sLuoA?I`Vq~Q z%~XqaHfcwqv%wE1;~88{xFZ*jsdbQ4IysceQl*-H>k43|y^>N~NASQJiM!57a}xwx z8n-=^jLLc>r*Zx6x{Z;#Ixu_~iS0`y=}eVpJIuNwk-?7Jv+PFRpJ~uKz6U#-D!i|1eE;eTLdsHXTo;K&)+x z`PLO5ie<8qp%iefTMA;^o$)(k8~ceyPq=!3kQHu?x#2))Q8+HB0wap>xZ%Zk+#J@=wFoL=1R>E8>sz{7Lx|r7nKaR$6C7Mz4bU|`SAWDrJdK`Gw zyUUKn0e>1)UWW984UN!j97X7?_I_`Mszqw7i;&`BB3rFpOE=6VibXw0H)8%f%KZsz>1XzxlUqM-FUdB5uw zeS_N}BWvSOBxSEoB>T2|^&4+8Abn+Os$PUtdT9jB1nH{VaziN_H*a{+Sk-!?#|kQb zebb1&axwg^HsiZCt`I-uNL{s!fQxU^fT1MRQZ$~9^<|UkU9PAbbY^1NEYdmX1qGA9 zkbii+0)3sdTgP4tOwKUL9z6wS4(?ov$p!~1JL)dPp8>>T^$`43qSho_RGQ>iea$u3 z;Lq+vs(c_|4emnG9ExW$h*@B;mT(wFd7p9!-HMwoS* z+uK&y?|8Z0#a&uXypPVrHuAtHXYQX-Etj^?*tGYF`J^|{V8L_RR3%-GyOzjSr%j$4 zazmY9x!Lt^z|6pxh!4luOZlx{-DTt9{vpiJq?0>*-J@U&Y2R>5OGkTKwUmdp!VA+Chko@FGgm9S%$f=0 z!U&~?k>14-rkPZG48{t(vLFuw)jGc4h^OAl(0mx5G2#Q2qlNn~*`ke&WYZBlk{-wn zQ3V=$)j+*MHovV}1-u{}IF5AVtF6`E1UjD?^m-KNE7I%L*fU5KQw!a=`Ymf(yEHyC zzOADpFnmq-n%2!-Evq}$*zN0E)~%`b#pCWr6=87 z&g%N6!EVr}+(@x$a>#IQs25BdFqw3L>YEbXb{5+zt6FTZmiHkLHaWOgLH#89EQ|Vz zkr>EXUvr)r?3N&qMKO|4+^5JsZ&T)Cxm$xXw%PXAjKunKS+zTv_R_{AR}Y}tC+OE3 zEvXb4d^{AhZ(2IgtHhkHcw4;-EGLjF5a$f0TDH{g1&eBDG96XCBs{ENP%Wb_N6B?_ z>f8mk*AT#Tbm)Dp&|=jVO?qtOL7i2fTLS${PV>8ZBkg8w=?JdWfq0+&2JmF;1Z^g^ zkzSyJYeBKQFBy$_L*m2nY#bUC_D0y}dSi3L!STW%1cAl}&4Ofr<9@-4>4 zM*Tu>-bB3_5x#*`nx?*7wc1w{0(~_=7X4+G45ZLh$Y~Pl2Z^DBilaVyhGRPwJt;%$ z2|Gj=0Urj2N!_^8Z-${@=Xx_#+p2*9lc39rkfA9tZq;NYD>KB!5Lksg&h-Q-6-j}8 z*kNXJLmp*-grr1C(5lI98NBEoxC>XGE zXu13hjZzH7?&_@Uw^~m)$y#= z0b_ENK8*DU1q`Q?S&(bpF*Xb*S+}`U31rG&Z}&ov$WiED>hmx6`I~(H>u>M|Eb}3_ z!H0nR_n5tLm^buqLJLoMjCc%3{}#|9F#|xwQ@Bd6Jihd1xSCg7&vxHh6krUW+n4M| zJ65s>{|*ut?e9+|J$@Lg_j%&uBe|5}Uwo6DN%y&a^gx*Qr)Vhb`WxzRNaU`jc@dOS zaO!cEz0^2ewQ$2ej%q-Noa-ISS#tvc?Y`bsJOG=!mJFN~_J-AsZ?-)C>#z6u8yCT7 zPJT-9>G(~ZZJmqkfm}T5fza_{9pOA|e865sQ#OI+h?CJ?U0pQ7Yp9Q2trgr{o)4i% zPl~A1ZN|*Vl5~_>lS=5nKjze5Rgil|+{O=7c)~|N;0-@2ZqEk=?t@-<`$K~7L*DQu zDW(H#x#3u1*-~{=63rpX*-(6FSXkew%Zax@?U1ve=40N|w}Lhr@kvHL_pZ(%M&M_j zCdM;}Njfv>weI#RTEg_gHSDbN}0 z>E?tmof_`8{!G^o-!$R2nyv89e|Kf^Z4`L+_S_&%{7XP?5*By)eE(-Bg}Y~^QR*Tj zcR7;T6_)ojwEMKu>194?ouk&_y)}c+6sPHC0hVU>Y&D-J=bJXnTjksvF4A&F8}AMs zruMZ%=u&r9=y4U`yT&*v&bQD7lsDbincjic(-yWjiK=?`BVO`as+AT44tt@{>G%PqH;PtS|lNB0`3*C ztpPeM-V6WKZ5zcny%N{yiTBEsd3S;ThJp>Eomn@duHGrBICVzL7T;_UBsXT6g3A*F z3^_Xeo)&oxDi!ts+X+_bahKK&+5XJhNG9737W&$an>Vycro81ETgDKjP!HD&-W1^8 zUy!AiO=`oA!0auHa?pN@RiI5SG zH}#wgTyVTs@85XNc#HdsPEVg;-ZYIC58pK%)XS8*Ke6YMIc(>Odsy5_aZiieGoRg4 z;x;ajcyT8$W7k?J_{6QfoL#q{3c54I-_8&YY_|B2yyP&H7#B~0gRsJ*Aa6Qy& zy{}f$GTcD%Yi3Aime0LQsM-@=eAkd)?|J#ge)U_TTZ;)d^G!u6|7##MYBCcCK3+Lg z_KwnDePqq_NsEpZm52L5zcy7^R6moY@~Jymyfw0cbaby3vDj9^bWuxb@bA`CW9QzbjF)4^MUr@k+Do(}@pfld=x!ZVl?B{kdwp zjV!X+IqIX;oiB@1>Ew=hRF-f!ZJ4ZzK9PUZ4x$`Cn}heh)|aT;Z2E&o{7 z%sB7QqDbz&kc~$NL!HZ?To{a;p@) zngheOJEZe>b(IAij1z7A4G{mF0Nx!KrF+_9f%&+j4fSx}k2ZwY5>n5t+g99$KYZW1 z75reUtgvp=u6ovkozWIxX>R1NRZtGd0hH4L3r9A0N@>wPUrQy4LkwdWp}&2epBhi? zuv*1RKuI#~jxNi+aZ}B+C|hF%U(W{Gdx-S2|LLS#BD<_DV29!DkHOzx*&B+rG% z{s>FPWvI7!#k&>aTL4qYz}ac3+oo9m3~Q}feGgPV%#-6Kb~et4%bCqXRrYX2KOyaxj@ z(2))wv`dPM4Y(!Y;XQe1IhZ|N z5q;IOr1OBz02fHm4Df-3AZ(~uVp&j?vF#1GVtTbEgAWk;;K&yYXyWBX@U>v%idnq` zm&+Su?>!|cg@Dqtb>Ec?gV{byo)o(lKNSNFmTn#Gh-YRhkeN?$I^0W2zS)XeoPNos z$j;f52B%vyoW&LB*)mo6($v2(N-@$cf~v2NmdLj#om3BnHrBaKqL)*s zgtYT^i6=k3cMAElYew$yxX%@_`kk4pwbqxzsi5B1wsdsTU7Ad}Ae#Y><&ienVF8w` zi)C9=IeeW-em(FTGp(5@i*#|C)<~i+mw=uPO_jCD^vg&}&srGqtIftk@!>dbHpcEO zn(Ncox$>!+j7uM1<4a}9rEz%)_u04M*4?5^y!F5WJ5%G5{V#Mj7;K_gWXRrhOAFZ> z{fXpGySCn*i?+NHzlUDW==N zkM|zWMEtqaL;G=p>(xjvPH8U~Qx1AT`nXTHau4K|4iVUM9 z@J+P1|I;h)i|k%ViKk+g6y>A0OiGGGWEa5U9@OCh%nK9&9r~!}eCaTnD%T3l-W{1G zrDHA6L+2}Lj*bmkdwu(c_O{LI!`t{4W*D?|wr*+xJZxc!FyUkX<&Q3n2L@JPFyV&PJ}_{zDh;jzlIq2MU!vt{ z3z(0@5vz&5fYA=4U0gR%PYaCi+l&w#_2VVnMR+%60y_^yui8ypsyrz^`|OQ0;`_z4 z;QhMAkR{-FTmB4qjS;TBlQtuGp%q+fc(a{FzDa}%Ct;+BM%tLyrv2&I9XaSKBTE$NFT5`2odl|1ey z6HE7hd~gZq%B5qd4AlJ-c6?wsnda2Ws-dCDy4WyopTfY0st}E7yO*S~4-vXvGu|;dh z3&n5icdFlfx!nZD+%%w^InsDKCd?=FMH50fWeg_nCAeJeH z_LL_JGE0XwW`^5@3nX#eEZ!N92Eaga6g>{K&@H>+|MjhKB6 z-i)8A!F%9lXz(65YQez`$OCr{4c-r5vcU(Gd&Y(z1b+?+0OgLm#mzJ`j&&tt0o)of zTX#YAAB}Pfx^BYGCbM#0%506)FAalA7vx9)@V=acFX*cmK`XVU(tce5C$t>T@ zGzX-cZR#n2&W$MGxa6Y(RBT6RL+ooV`|3f_SwD*Udpvv&nNfjL+qXw z*BY&2_rvUO6t_oQ>oB`##I5~^zpbqe-@8oZ(SenOD8kn+p0d@wxMgQOmB;Yjd<0BH|P?|ht9u)@>SoTRnN=8yH!mh zKsO&x#KH1vOC*f7wwI0XtvFy=9~q7e#G-A=AZ47b9h-fZrP>xyQ zv}H?)@GSx1EhX@#BQUw{&Lwr z_J&W2Km44~@e@h^Qwjf>l*eJ${<+X0Zu76CJmQXudsy5_anJn93vd5g!ppheXcqs` zGZHRt?Qeu0ajoYi{qH4TaciFz{Nkp>JuGhRci8p!SEnp?&xm`ttjZIAv_j~c!|tfK zr^QwH)OnLf-uUWu*X=&D;Ztj@vrmlP@|z7=Z;vPYkKN^1-yZwo{mW)=spHq@KtX58 z&!|Y9<4k0lKHZ7?hu5ZKF?|IC_)!)5HztG>YL4gez?vP{lcgi5tb@bXXgi3@XO7Cv zaAUTvbonTDLzYhoN1{8RV{p%z2V*C_?qB^^;hphlXRfy;mmN%|^_N?V!&`Bg=1=H9 zJv`JM^2S_tW4{pUf$+?-<9Bl7#;#Y~kIG+Q#~qpYbXkLzI$MGd?y8Jf8NIX7_4~gF z%umlHESIJ9RqdNN{{Jg|bw=npSAEqupW$m4NV{9eZqF;(Jy(5YU(WDKU)iq{I>c>$ z1H0im;YYo+=PM=tD$xt#HeM_K68g$&l>C+odl5A78gG3zuRFK;Y!3aORi8cW|6QMyukc}VgW%bCZuL3ww*Ry0^Ju5!*Cqb{pY6j` z*UPI}*I9QXC`7k2gV`mRL8)S<-$T-Uu-_=+mC~ zymk^yc=>!}dbRwSP@yt8s>*8Gr5W~j# z7QT~UfO7NR)X+y~fEWfXnXGk_#ox7012JR`^5h!fRpGcuiUWF;p9)7iadSG+5)_Vs zTQ!F7ZB^4lw-)fq0E*)8C@~tvuI)_ilLnE%=>= zecb#NP1U`4rhN?lH)l%md?^#&@Oz7_s4N1wRJEO z9}XuI@jm@=bc`h)(P+lKS0^C6#S@Mp;z!;M58}jC^sTX7bknd3H#6t$8eprZAW#ty z0Ea|UI1Z$W5xD96@s!ZOyA}o%6xgoGb;I3sMl8p39dKA?FtO8|F~f;XOs|e_E5XO` zc6SefZVwpFb&lKTp``$KZ;7N^)rKW_kHd%(FUB$bt#V9A`xCJU9m<3Hz+&t3vf!t6 zat`Rw12u2BmOGlv-#8pvmq_-~<%6xs&BH^y*N>WRe}tzBG2Fe;5dE7#vLl(8Yz$O) z4z?!O8>xBRsSzP()3p7{2d8quaQ8;V&RAbgjU3Hz9QC#)ac6`|+cF##a#RMbNo33B z;anyb<+~o^F=&zyUNp5T`EvNWT%445Ye#2$8&;7pjAWoKmf4<7QcZR4jA#1>-2fa1 zQ(+Ald~oR<(7v^8HAHTwU6T~vmP;i_+N4o;>iO`_!CV%`y~AO(kuk$~c*PI~@p{*R z5w0iVJ$^G@Chom{xu@98{H^gsV&m|dk+?cQ%?F-|c7`YlH~cN2xp%1j8J)xh;v0nE zRid~JVtpiqmu2I8hUchvSF&X|6W3yl@m+K-AeL?g8Ne%3WqTRt2k|Hn{^Q~*+>6Z8 z^Dsg1*nHOm!KkL_ymvCAmMglF8?x$s+h&26^WaiUZ#B8+$+55o%XD~fGK_a=?n)NX zxgonH63?zprisziHCY_qiS3~1l)XQklIhd-m~K-nlN*YuSuOPAZKRT(z!}b%`5`~D zQ8q{Lo(I9FXTIXYxtQ{MB!b~Y`-$zK{KfRC?LOYT+Ij~z$2;A|=1paBe0wI7i(z@P zF%nVe1}J>pEa`yy9iZ>A|Hj^9cmOMa?-aINxG;TS%k-;8&3;cyZ_T8Q_5P@3+wPaf zkP^K3INqm@i_+Nw+3v|-{BfZNVp#!}Yt@6&tWX~c!t-V8a5uUEl!y%vWC!i~ZoZ#D z-M~)pY9DVYLO@^U`k{ZMkA0ay@nL<-1YLjNp~CZBwScSh4Mf#`c;Ze;zO<&3napC` z<;-UiY5(#f{^~(4rM^~&$1kg;UIrKAm%HM_E9`KqUEkEb$nFfYyH?yyE$9ZrW5%3< z-`46kOr^5{qZ3OpkSb|CP3(d=2yknY^F?v?SsxO)AhPr}7LH7M>KGLBBmcrzp6 z;*Rc;ar7=PzF2R{8cyP;@d&$|hiq$aF^ojnY?d3YzCr^PE-@JKO& z0PbsJ8TesB$TzM&exb{aQ~JdrFxhWN2ES z1;@RNiR3^ISe(lY^6`g7c74=dsXlh0^Tpko!0NSp^psi=N?R{|+yLJ+D*t)qoVR^q zCq)g@|DChWH6e|}JfG|fHt@>n_9WH*9l017XEuIP$Ai8I9%_EECYBO=)5v*zi~qXm z@p!GA2BIU+QNEyG$Me@HQSR_N79=@{GwP>9;GmX4tpcbz>2BsDG(@t-Cl*yaRTZ?5 zMR-BF!S<++pQ&VOCNMX@-V~l{T2UWegzx>fyzp^iEMH41mDq*y)463cDPcNs+|37$ zySb@#%Q56qW(dD%t%gigWyYBSb^_!vYVJ$Oh=#b-7ZsMsCYcImVyem??gppbVnu1 zwR&TC5ng4W;#4?(A1XrEz{{ls@odZlRB)M{IXTg9?5 zP>f5RB64#qj!(px?;i4faDz!`rKs2fFnal5RwR@hR3R%QfBvzNNMCja`tHcZvB^>` z=vx~MW};Pb`%ubHhL3KgWdQOzZy9a<0H$-`C(|33`YFZF_^iA#axKjy1J1*T;_L(R zpNT%af*_Lsv$An!Jm=2vBK#hHqjkxxkiWxQiY}F(dz*_tGX+1KG_L6|nq>^X@59&v z`KUEGeNls{RLU>7fAaK`+z`R1zgH(6MKJzi%nDA$Qj~jW4lnnQ&^J1I<+GO_?N_A# zsOOh6oGZja>*i}vShGV%lN?@*A1|Qy+z`W*>i_)xWB@;yXLOx~QmxecC_eDH095VS zbR;GBUX<#ejP~lL>+0+*O6Jn>);OA4Y8!xSX*FO0(aa*cg$JIr_|#clR-r#R|j!%x(8IHdAkvl@x&~L-?c_;uP2u2*8MdXjgEVR0Wbi*8Q6n7 z4>QyXJdC5t!g+ALTw%AX-jph5aj!e#QaM}&X|JO8GeiGht?Be_vqd^KB-t+GVV`kd z3a0hgg8ur%8M?eDT!3Qknv602SiF<_c2{PP_K zkjlZ;=LSW-cHZ+I9*0^Fup1V))cE%FAqoG0tTTU5!o{uq5W6XHkBY0F!|xP$-+t>_ zaht~lexKwcuC-t219@0sZ)(?Lb!ZUXGQfgPO&`zpOlr94W}N$Q;Y!bzxb?N!K!YEA zCql5|1gTeXL_H%f5(+&6;t6sfeA&<)6 zzMb9X+h@*yay!SLP6*vYQvTuK{MCMl)#=XV;w}?+skqmR+lcN;(XhC--jeEQwaDGP zp`{C9HqmU_rc8J(uHd&1XFD+KE88{oQ4S8(laY1y=)eZ#sHHh(9B z>}33Mg}N~~!eSCrNmgS&$;Pw|Dxl9^efk5$vY4LbGt#peG);ee7|PRuak@k6a&1P| zH`v9R*71X=*PTdDs|-1kOp5*iwO8l}SfFEV}WBbn{;#Vj4J)757@iPomQ z(Cd7DTviPCvA>;8Nrpk)7~a*Ux7uCjG)T`Z!uvI`Jh3!=!aT+ISpm=cl4%1fC|qvzEWj9e%TUR|&9j zS1e04qAa79)$PS~R_&38G=9DmD|{fGiR?g<7I{R29z{2_(q5II+6Z52gkw9R4`~_* z6x=em+yLbQsQ5Roum=ba&Nh$WwS(GIZNlBK0yN9Efi%WI1N8zKaAtj_@Dq8$>45kY z0hEsK#Cigk#;kbCD2P8U{36IOj)Oc8AL6CjQAX(%w=Si3Z!_Ckko*{A2gQ5JrSHk{ zHDIDO7IpRZ+D`hgUQsv)7l*Irh?Zz{Eq+OmDQa|JIH%{M9-4qUMacbTt$O@1rVe`+%V=R@i2jAi85zEIY3WWY@6W2`nMm`q@lyW zZ%u0(naws*$o+D|dJq0tBx)jK55)%t>FOPva7x6n>{obm@Y^Gej|STV_G27ADelDM z?1sN2>AwD4d`r&v>7mrPX?=KDp$cv{qN}Kd&*35JP5sTS6Mxqy1H=3Y|oky$LFG1na_o>5yTg9%ST^vJp?ks zfD2@)r+#LXGr5ou@0`}G8;Yb#$Zbh^n5}+itJe&$F_Px$z)_@&h|`049l?3N60CFc zFOi-L;0wikX)BY<4^O*y8+;G;p2>cLZzw}oAzrC@72dD?Z(n6uyWw{w{8p}9W!-es zDytseuY=!W_+1OXYY=8Pz+4F~rh(tx@N2jl@7T92NJ9IbS0WAz_fkW8_$|Ka8VizG z*Wx?=;Lo+!TJ%k$#gKr%=ANXzm?+a%K>Ahiy8>|mqMHB)yh{E__7Qg5HvHOid|+5E z2HCbPEtlw6;!kDMF!tZJtuI0Ab(RY6k7TlLz_xAKLHty->(6AP9{5xQqb=?4i^lpA z;9@;RNjbOPqCZb!Wn<7ifR0nl1GMpUVHI&Tp_suhS zfewaWrRp80Kq*l%W{lsF>+1Q3+Bk%C|-y!jl=rU=$pnNTruSNM%o)`v} zXavLfO9GbFo8&XH+qMBz6XT`#>u+Fp*;00?9bovlfd{#1Mzn=^)7eXC`?qaV`Vg>I7T2>#eN-%J=vor72N(5D}feO-UY?!;YU z--&Bou-U*^JNKQ##cQzhWB zyhj##={W^{y97M?7rxTVPaFK|(0LI4?pJ#GIST$`CE(FNdbtaa{(YCb^q7x=pLmrE zkL5pn`6b3zYi5T(`7+^`zv|_|557$JL$ko!uXf?_tpWT;O2DK1oPE6uzYu;^Z@9!d zDUA2?|2%L{zrlrH1Han3ODv~67@qXOm0o$vf`8HqhDS7yT;;;Q5`Ir!HFNtireqIP}=xQ%LN5JotfJgcdE%LUPBa3F%Z)Xg68s0Cy#5!DppUD5g#a{j& z0)JIyFgyl7bDazSM*PzV^v?-~NB^9qF8oFCyKt#159U(}{s{O_m4HWnKfc_BNB(|q zd1?NjfA<@``eYpZ$7aA^x59--<6|ZGC-~EYf%s3|=)z-v@yv~`{xKhg|G||mJfeLB z{9&8@e*6gEw#tit>#CXM;gMBd{7-^k9S#bDH~TN_PrGiq#M)N^9_jh#n_T#1@cSM3 zM@#Sr@juw?t>4c!&s<+^E#C5WfWP}?z&|_#JktMy0gp!YrK_QSOTZ)jTU)*SNwk)R z$7XTHfX9nSYukYTGsw@Jkhi_Rux94|w{5Kp|2p_>U0a$SKYrv-bluGSH{sD9xDfmc zXQA{`tiQ7yeTCy#W5h z2K=VZw$6^0ksC69`-P4@3y=SB`SLUOVR*E60EbvhQc?HJ_5Yg>>8vNdr61#!p8Z{Q zwfj5js>XKL)mpjp@@;jsQx}1!YEBkCRa0{?=y{ziq!NV2e$f!hchogG|G2Hf+B=y& zpR$^&g~W}P@|7=}42?b6;N~hxn@+UV*+}2i1%Tfkn=IRp&h9#UVWttV+M(@F)rJmM z&bw)PIzOlC&24qfxdle}zpa{{4&~dbs-~`-`f?jYGZX()dq${D!JE7?t5#BLVlHIyH( zYs579(JE+0Az)7kNeo%J^OsE)E;=7e*-GgCYXWJ3=;Kw+qMsx1c-^F>06y&? zmQ#q30`u_y0KHC!8vt??-o_p$$I4y-Bpw#g;pBNpp69^A2hUTXUn_7nCkf*NOzNJm zZoQZ(Kj~(KuhSDLh!4u^VNYJK z(?Vd6^Vy#w;z>k&S`b6{;A3SLvlj!W!;OBFuLMyWw02zVax-x;D>lpviE#er6H>xv z=acvfl1m*Zwdihc(cOTiyS(P$l%*JU;Ac#sBO%RB^-sCzeI0e(n4MEp{(RSgMx@mt z4jd`2nA|X+pE99mH5camL<_*#A_hEGEwr93$$+|L0F zJSQ2*3I}xgf8s6wPe^~AgB0BJ6DG5&Oqc&TuM||31xP^(sl}KXrQm8oUTgB;;U8-r z)CTdOHkb#+QZP~^1^b`#aN*A9L<*?MJ0E-wsd%975M^}I`Phl7BE8ZHdgZegKa6ue zkUODKp3gpP&oBH)BB;Ip>PHeW;{5nWq=^ts;d%Jeaj>l}96C6EdlOP}fbw@n&UUXS+nsK<3C7Ydi$hxCG4c5b*nFH33u45&?)NwC73eW|G*oW7Y$bKibtyu>kbf6Y#5wf0~P^%gU*V8g{AE<6e%rI~}&o^q1@Og=aba zgj7`nbz6O>(MM*)ghI%*F&%C;5k2im_Mjj;q?voUi|CMx=#a(sh=FLIPO?Ri9F`It zc1!e(ln8^w%+M&xr$U_mGD&|#(jRftpO*ATEZylF>8nsKSY)vdQL6E65Z`*RN_(vA zD<4xb-Q)ZZi!-9;Kw_cV7h1WHD8&Tb@UIk-0*OU&G$b};+SZNE`VUuFY-l1gZ#I0j z&h>_Gq4NgAXFKx^UxRZ#`N(+nTd8i#(0N|X?fx&ymzWP&bNY7OnHj=clLlPUf!Rg8$%OIAJqlY9^`asv9B7xCO18 zx*Y`wF*x7ZLLMc#xgk&;GdpP&qP0IKl%{Ke9ya0t{URCJK$P+5grrZ-{R zSP20u^C&@Wznz{IO}^5~T?btWrm}Ljre!tJlB*#OoEY6L%D3=KjQqRP77}_T;9BVn z0vsHVZ#pq?(1$v3bd01POx2?X&3N3pQ z+q6B8l}89%7#%|1)yI&cLQjQ79ZGW<862RV&f~&Un`l&_sd5f&pq7H69S30?2K_LT?Kf(^Sl)l*oa)@X(AZbY`+-frS~fXV`KrmWXFxu(*Bc2gJck6i z%0i1UkWvv_4IZCE;Xi+!zwqzAx61Wg{zGaC8@wQM?kKY;_a`j2rFy*agMgw#=gM)>Y3-Z_U?Ho?&EdgdCW~rg)-2LGVq%JfMz~kcdUx6 zMRcs(a?BT@IA0|$cVeNiOU5di|GiT$PUksc;VU9tRJ9u7F@V@RS+jS=OKc!==!2)w z#BhbHS@ZYhvVGGMKig~f8*G2W4~XqosG_QdZzL>+-os43ak~QzSaW*HMNw;|DEQq}sM32#nU87x6eQcv zMN)N=od-~ZT*mIH*P#;Yq3}zIs8Ie9@-t}|sF#LhWSBtd=&(uYE_TVIg zygg1%Ma|fC!0i@lRetUn1sUDXZ23D&Cxuo9Z`i&qC}5#XH8rN+6!keiUN)mR(6%2G z7B5R0P+N9u1&N$R4s#s^5cd81%W#h1ISAkLI5`dybb+WIdbYb5M)6@CNf!k3tTQ*9@-b)QOf*uZI zrPqwVWVxX=Uu<51GW2uHs6)`jq)05`d6Rl+R4)zc#jX@X5SiR^3~QIVYOM1^_f)Y( zfPtV#sHV=CUF|9EYA?IWP%5P3KfdQr)A67CZE@XPT&&|&T+R4nmKO`^zu9cMn(=WY ztMY|GU^NyF;&Vt6CjPG}$4`DUYdI=CubxjMM5uWhW3icDflPGO4@OJ(CFI zrS=b_Os&`kHd4)(vlB=yRzmXoI$-=Z_H3C7*iQk@FTcxl?z1ePNM;wff;+ha zyUd02aCt7IRJ(-e+%F0pto)a{>1j3AnW}++9~uE2K>I>rI@w|e=M%iCxqf*=g^MwP zO&OIOP_qg;w1kzr0ogLAjFFM$Yv@6fL81KqL&&Gczh7oeUEU%3>ajUxu9!Ld-dP1> zyk$>0pM096YJjoKc8t!!-dQscrv4a>trbbL|C~!l)uQk6j?-INDprYY0Gh2g9dAm|)J-mZ{AG zid_}<@y$5IPOZ<&gkzKQS`Q_2rs}3%FG+CqH9KeOlBtUrat=W9@@_o`JpWRSB{K$d zoj)fkw$`QEPvFJ_i&lWUm7yNQf3nXPA{S5aLL5yaA&t)Z1G2~zc2?7CUY144EW^xc zw&;d$vq1Bj8YXc|Nb^!q-YXKdT@|%l+tJGx*x^;Y+yA5$Z;Hhkddc?U!p$%!t$tFrU8{b~08c8#Wa;<(vwXw*z z86fQ3?V`>wYK$*DqX9nm6c>iq86OwdtYeiyURg0fNE@mmRoS!}X;yX!LpjY{=Y`wK zh&ALtfwqX{+eQ#}o;jhZ{Pqb;?I^&F9S7<{Wi%m}+Fu5L8`YWsCHsh*?0uY!;`Tg= zs!4YszDIW;9y_mDz1aAIWel<6KREx#ui@EM=uP(HxZe5szms9w$n6SyfDd6}1R)al zw9OMQs^g~6{yk?ew75e$F*-g^3SN{~GvxJde_nTc@|puS*>WSJkeN|4WMs|L8SRsd zNbeg8-BW%|L9;6DYy1?v@JBxd^#%ov{-U0~usF*S{HHQ2k!n)}Jp5{d0O-7(cN7t@ zNs9Q~TiGZy=y`Ik>uuY==Ua1qYe-rQNJot@q}etN%o_GQp}(o63tKfTAi z^geU$^wLshnCQi3X$d#wBaESr=EFadj6yDTW}gV14vSMm5M#Z+HSDPa&%YNxj3M zlso$H7_BT<7M7Q(BKAvKSuXt9S1oPW`F4h!FMLkPmIwpgPlRJl&SipbgbX?{1*qkZ zupOY&eBPq6EXP{q{S8gdr=Cz`{R6)3S5re6w_Z^ufnMTRIuB5kpFX`fd#4~(Ll|}y ziRN0hPWcL;d^yTo#c>utUjOAbfb~RgZFO5Yhm*&3U47{|MQ#PHjuKWZgL(nz44MJ? z%B>B0zW8)G^))H#ba-NjOuyZAy~`#awaV4hChqT7leXDwowt0A20#m;aldIH50?l6 zhf80+x`G>E;lO!ZdaFVY;Mz5)nor<~Nj)DQJfVOuYDUu8yrasRy3IvA`tUrW<}Dic zp5qwwC!+s-t_qMs3K+pJz;&j}rl%h(6EW^_es)Kd#oH);&|k%pBgPfFR`xOy4qVf! ze3r+V`^weA`95JYi9|Vz$VfT+M`Q|CHf7{$0X|!f2P=j~3;!hRC(LA0T6?fAc$^b< z{%Mk1OxT(DiX|H>)_#dLR{Z+QFHSp`e}p#ZAU+^8ON3Sy#sMpgG(Yr21(mJ0Ls;6r zXYvpYJ0B2se)R}?_jj!feUqMmQFI0XntBjIG_EpWvOi&<=n9HJi~|EHj0Y*ArrmxuU}!5hlKBk z6b315e$zt4cBq_Ns1Ms^x_p25-t;t!`Nuu@-zoSH8zeV4fBcdjARU$r56lS#@X zT%5^5PbPmZnVghN*uB|XEo`Z(972-A$x=Cd!7_6=`#9%tN-B?N}H4x}9}z;N3xC=QY2_C~3|o-bHm13S~%Vo~W*C$uJt+ z-x5|{1aip5MadQ${b$He#@Qgkp&w@^#_MP$_i=J8+;n83Tu3|ZFzMJ=Lna!H!S-Ru zV#&99N?z_M`R~3+B}b6L1ww2vaUnl(xMymx0{0sUlR^z+Pc$FI|wHpn^m_1u6WUS&$$69TfyY z3ctmEpsxe*aaN)Ip{By6Zqn~#BTZKBvV7%|4YY7* zm4Pi>g$)rYlrf=}{^mgGACWvg5?N*Nr_fX8i>>u=?;P=am^kQR;=_-aOnl!X#6$!s zeD1=TB!AS>l3&c}Ph0+KA3e8fpO~103~U+IyOGiUu$(&#O{eQu=>mcjdruouhVr{5YR zgP*OOsaz;p{&FoU#XByCHRs&Qp|nuG@*s zmYw1DAlXS(%pg0#f?D{u*#)&MC^Hb&NtS?6U(sm?LFun>pOD&pi{BWz6HG7}cO&}~7kJd7AN8LJU z!t_U}km2I?3Mq1 zxEZ?}ipF%#`y*92T;TXnes^7C|8M^~^oOTIV}&xF7e3e)D(7k9gE$*^@003)T(`3U zI8yiqZ9pwSk7|Y;FH;Dk&(AJ|yVsT$!Vz6-_kPY4!rh-EA;jpydn#!{P-!p-K8sAJ zV-q*dK(B|;zyEC!p&l)`yVlf#FMie}=GUL4ToHuSrzg(`Xx!mu+u)b{*JAzB*d%)i zro>m;KUTB%%Z9X!jf7s6yWS%^qDsb&cXi17`h0s+$HB@^R7_7hSKn4;P2FiEe`T(| zRPuwBc}((UOtQ|UXC4CKtFsR`tB%)=dbse1&zM{&e1^DyAO+l(R~VPZs|%Eyr}f!j zxu;~++2#4lY#YkKDD6Y4?|-b>Qn^phul(eT(>Q>9#iKZ%;(Yn9c?vsU+1!R(f~p|u zW*A}r?{XetbE1=M0*=(rC&1zA5m{5zh;lYq`ktJP;&cmB3jLgH< zj;lJv*A7is)Wu^@(=l~k0C0w|lB;%7(Lbmfz-4F-63W{jn++Z#h;$ z@-cr?nOPUvhjEvC?kz5tL)FvsZ=ulaawGJ@>G{nZ`dTCO71Q&t;ZUt0yd8m1WwO#$ zSpo8VOm_RKO3Pg*3TM1lN%t#1WlHx2pCakT=)&uZ2capqcf*B};@&N<2cfC`Ew9G0 z64gi;asPU-f^#C@o+FmO8`a9A*^jtWCwuHu7EdbHGI7Uz#2qV1T#b)7K154M->7&% zzVnZ0y}VDe>9?OW+4S5eiA@v@SSQh4_AO`C2AaA$Rf|(sg9GK(!|`%!RbRPv=!AVfeQ1aj|h0YCH#Bw(y}VEC&&`PZD8Y># z!v##>?4x)MhEoIC7nTOVnH$+8>rj3_N43{-w|(t#HfK8OZ0GC!a)kjO>OApDPTbA0 zp-=EkW1f$C@x~q6oz;zFfVR4oV|Yp}`zpONf|6bT398lR!UScnkl!xIdsI-Zvju~I zE0pXlpA<1A5Xkrm1nfaOK;@KM2syR6Ii2`8<f5C2K^@sWq6KCTQ9xtj4ut&;LqGyWh2`Xq@qFi-`)54eim=!i@6 z*vEA>mrS0J$%D}8@!K$nFf!PG)4VVvg2c=q@=A_ zK6+3-LM$J<>rz&>O7@MRWE`aIXjQ(HShRz{7h+m0R`hw=;*Ae;qAcTh}Y?HJ9RQD@gPJR5NRG^iG7cHhIh7vH=qR7M46$LcZ57$dJsiQNp6$V+XHf)ul!ll zMKXk%cY?=Rc=^fH1>(WG$nyLONdfB@o6vY~=EH<1c;KoeqRIL8hY1`53x6vkq*G)g zuqXp9HhMu@+hmhm_2^9y?) zP`HXv;PJ|_uhw$(cehpO+fxwxGqq~;azRMho>L23j*(3bNy%hJAm`-86_Ul0!_??% z#@~gTAe3!XwM}oBns=BBJzC3|uuH~T2Pwl^T8)8%bo21DOS4muz2hNEAxk|(1wxR* zEpwT)}Y~sa3;1wmH)mEbKY#i3Cx8L=?z3|yYU7hywWR#vkhUMzri@YgQ(jj zuiH=FKYvJ*_wy*T#83WgyY{OoPOkEt3qH!0-n4;d&54>6q+wMLrghxFXdgwP35 z4e+X`ZzhO$jheuk1OHe?)-FPo)$ILdnSpOyGC3p_amcL*vIY-vMPOU?&TCd?Yvk?x zY-J&B;%t0~2_d=Mb3AmT#hVu<}=mSG_U(I=vN=S5z)-M`FAg!%Yp1C zTUzrCUUPUkZGCo*K2>u>BNCv zprzOPepP1VG>Ta35erS)UHg)!P*{F7C`EFy-8;KKN9Wg8d6vV3fWsd&3Aq1*nt*qI z(9(-zLy%kH_={}pQE9SQq2O2MY>jA(2T?ot3crzzaOC6cyj3^I-49yEETP2z;RBW> zBQcpMMEYfVP|FujT~dN8Kd7cI-|AT&ljsv45PFEZM?YXv_n8mqVjlj0rI*g`q4W>% z+%d&2y;TN_gfi{#CX6mfCtIy9xwq46h{9`NYth?qO!;$*brBfG^|L(cGrDBd;QW(4e zps4@Hn+q2qp=ke&Ie5QS9lS1jGq}6^A#3tg9Dn*OS#o_u3vI`~^dy!o?6gnQj$XR$ z(7J0Lci@C)s*b|$<}kWDYtdA#iDS-5pm&1k4ZaVB&e!;i(9oV=97E2YVB1%nt_eB6 z?iM*rInQ-d?;F3~?0s>Ir0#vuBfT%aLKa(mo%9bycW<5M`Em>$J2nBZ z=jEmcRhFmD-Uba6>%_{wP9>3Adh;GcOtW5Mk$5m7 zRamjk3m>5?4O}>E@`UjUodk6-x^Lby>cPp~c$X@np|TyxaT2q5>XW3h{pYk&&YAb> zD*VZNiE@lDJjtctQqoN6Jvzy}_p>lI2>@EqA(i2NIiGS`JT}g5V=3G6?!A#GP1642 z1*(&)Pk7I0fqb~6y@g4`_^CyO4@1v!f(M&!^VYGcaq^z2LH1|f>(qh=19H8Ww>%s#1^Ly|uk#8_VE z4}8oe%9x*e59JgEojFpZGmGzsqj>?5HO0_I=gCgJW$RJ(+T;8W^%`$($iZwP~5{T^NWuT`%-&L!%#+o@8ojn0erQ&|#)MKpluQ0E^Xu-LQ~ zq>aua_gl(@;OQe0T6{GR9pIr~g#PLMs+N$pluO&e`!#Lvx?j__^L|ZR;(kqAglS6^ zCgvzA9(oVcH6aMQombzlRrmzcWgZwPx43a(l>fj0QkE^#ls$i+rp&odQ})CAG-cnt zPg8c{KB6pJ_G}memSxUh(c{K;REA*1> z`U-VNX2{uozk6Tiw)++Oy^`T!$uQ(p+@~3HxR@~&lI`ID#(?3gd-TPE_lV}xXC~Z5 z=b(Zd@f8Hn{WFL?l?2{Ty`)qM@{`8ylu)^(6YVm_b(E+>#b%;As8Rf-pdf2Rr5pPy zZH+tTO6f5|BkEbBS*y{61kI!uO%+3C$@V znqwNxV-t+#lot)n)}C_FoFX)i56vAKO-9f><3)3+HlY~JGlb?DADU}4nni-@W=hYR{SN()0#f2oN4<_wi+`3djk27}JA{hF}P?bn2TbicN|r&<*kJ_pnmHoinQJ8;pc z=ZuSF&_!|^BRN3)3NYV;$LC_d_qdv7bGzsiHr@hl@h(-OX6L8-NYc9sUn6j(2VQqC zrxFwU@IJjZG{|d169PWSYeS-X7kUQ=`x$xn)OPkiwco9#V@5R{HLK~cSxtwenvO^{ z?UQO6#cF!Xuc;+(W#q5s%(ey^>!tNIRlHAMcRMv9ZIjPYuZ_+h*WoKP6ci;^&x5M8 zjm`((tt)dvy>>f$-%Vr<7H*`|g{n&~GVQN7P5VY?gNv-yMb`9gG2(xPv(i8a3b<7> zo)a^Qar1gF$v&<3cDUyLx_y>Mzjr%dyN8y1JMw(d`1<_Cp@VIF^|ak4%_%Q){0Pu8 zy=la)@as*ZztK5#kEZ(IJ(}uw-6Q6GQ-#X)EAKW4_D?utp!20~@l>%usHua~7CJnkL;5!;Z@%({ z*O-%S*f{iL8+v524PW=uL1V<$Ap{=PS$$(%cVJ?Y>kh1^Lv$lB?2K@TZFKJl!rzNE zI`19V^xr$K>3`?A+l%405;c^9_OVx`{LEgT%ttiIIb=x+E%)_Yjn4bWbmC*2R(>>SJ zn+oOAMH4xV&fDFDoo>R=nC@AMF8mJa5025CdTm@UqAsk}i>Ti!)ana~Yn6;%)hZed zS6i(dE`wUNZh@MeufK~Zz`(-4lMVhjFP&xUWkKRbd5)&~dL{}3XnR9pGutm=B5bFd zQInZbW1bfc6ahVofDWM^)m>N!2$=-z;rmOgGyzBV5CIracn)Rydlm&?wqvK~K)Z~( zL^PU2G`K`izCBX#?x1|z|48{>sPk>&d@*1uIo11Lk;fbP(!*Mv$M;4l4-A;PfP;>Y zqD1CpeQ?>g9Q!K1AFb99$ReYp+nocOZ1zqns?N{m8$oifaqssa`0yx#L6E-F%qAtf zZx5&IVX(QQdb?5&D2J9~l@@8NeUhjLPl4fr2%QGKJaod?^U>%`y^}L(o=R}QHG7yZ zM5Mn{!a%3t>!c(IQ^>{i5y2F~i_fHxm6)6-P6_5NfeDwgPiErZ=*=&Wf3@#a{5$F4 zUue|Bzo+ijW?c`Pbq42Br8)QcyM3HH^Um2g_p2w7bJ@CL{)8CCZFegkF4W^wj%mF+ zkaMOHM`WAx*iFv*o5XBua8}_aovpN;oUluzmiP4r>=bz zr*fT>P}P7-NnC@o(*;fla1SUFtUrI72(s6=96N(L>$+au!Hw4H4sPm4x`V@w>%fXe zV#NvW@GOxL8K21d^OY-QZ5p>)I15*5vwz-7=^1VOxLPiRueJ1wI{-QqLW2FsJ1hgq zdz6nd*!vDrr?mZN6`n1uy!ldPyj5d$;UoclE`-isyPawZs|Is)UjJ)44~E}G3Xh$v zBAtT0&qW?-Rs%dFFYF<&+(X{)?lj5!>77I#Z7q7Jnq`)UfUm~-+3#+;p~UaMQ$$d2 zx*9BAxH9+ueikBs8v}w zh-WQTz0{1;B^V0h;5(RR-hhKS{&bfnSa#op_-q2MksgHRD)%7CCLDFptEe2^o^l-B zWtQWkyUcPtu#3up2?`x^Rf_N2$&}5qYbPjc^Duj}^F~kBS9!92C1*|BU7oITR}ZeZ z)8J8?P;yxF=&K`|M~8!XR4F_cZTQl;)9nuDjW}$dh%2C+mOPNm_F0gu!lC9{Zge??j2a z3(*gH(ErU&6aB+GP4w?$^q8Qq0nj6+(D7$0oY%}Nvy|=4+WHE;cQCs^f#DGm48n7Q zQ?**mLG0gGp^uD_#H#FbBh0j;x;mfVp{w&~V0Gpn&<8t@maNdqLR|${0~vj&?>!se zzP(fDx05M2R%^L>b$Ew6bYmiL*Be@%?&z(SM{nMYcUQ}Zp)C6fIqz|P&EDa1efk4@ z_gjJRcME?|T2-}PxzpfPyHGl*d37SEc{Mp3uO>_J3I>forX?mR`;T^THYaPDfhTLV z9MfsbleKDxUekWwREnD^YSj)se8U}jG^wL-{>2U^f|S1B!ooo3z~9RNc8hFgV^Fn2 z??c}@ryY8i%aKY6Xn(TW ztjNCSGBeLSn+@8Z|Gj)ZVV}93IdjgLGiT1+;zx0Z@2f`i*a&i9c~cL%87GVtXWnpI zN83C0Q;>7w&tgb1#&&+)5-jSt|Lv*<9qo$_ekRPqWRGl@7DH1eAy_?o5^2fD;iw(zzHLX z8hKl0@L80Yb>5emOuBEnPbFnyCei&^ZzEr{%St<<5)$AdQF+QLY)#6L^x|!;#bRZk zSCp$%Td@R+JP}Leem%PL_bb_*C@x3kBTosrqJig%?iR!T9_lO|)+sPcJdatyS$MgD z+@-YK5M|93vo5;EpvQe92;1~d?yAgq|H_1zPP6lT(>1I>T7@XZtdp)*%MutVmL)0# z7usmkn8{ODu_93k_*EM5qts?n2IRdOD}t!hOKurgE~?{6y1lTijB&#dXBom>{44hg zSXI`y!}7R6E(QMUs~OY-DpP!+VRYv94=X%*!Mw_PbfH`@r^&loPO7ph7mBGe;Jc99 zP{S_RmKi+vj#+z$_mDpD*Cor~EEy#l@`Z zg}St?SjcVNq)HhJl(cNhmX`7@sP?76Y|0jxx)KI4><1e$^cmK)`w-jsSqXaSv)Jwj zNism}t{~Sk(go4kgp6FpSS?naML6kF-A(vbgo}*uns^mwrI_qB0R5k%tCK{lg<&O% zsyBy~zmQB5f762+wI8}lxO=$}_wNndDD28eplFVO;Y@3_N9lmFE6EHj?ezX(=XrzacoT8dYmmaXJjzM- z+S|%W78a>=qpm=s*2`pzvYpq4PP{vy=2i}G!f--{5v?V5pvt<^&WRWAS{GhPf`q;) ze0;6rfw%La`kfw8y(~4oMl`z0iq_ceuMsu@;V@i=2*YD*$U;C!smJLmE?Fh^Ih=Pu zx22~tsm9&eHGX`Bs_}PMs2bn6La*_~EA$$Fbp_RkkWypB-`3Q3eVLHLY=bV7h$ua8r>FGOgnTQ?%WT1g0bt zzUh)KiTaQcKTpyqL?;E~69MCOZhoUlK72+#NOT99Q$p5#ACMCgpH9PkI2++F?A>%4 zGo0=dl}=Xyjm4@`+-v^&6)f}nJxmp9Hho5ua-DH`X`Q#5wX(`o$WT%E>$n@coCNU3W)I=V*+bPou0sqkHMG0R?6 z{Ofs!Ax3-3hjXi$yr#L1=5`f4{$irK%c4U&_GY)^oVltU6?0WP#>~~*G1SqHqqrRi zDfL*MhVhJf+zfP!Fqn7esF@i>^0IohnwDWC-zK#(KTj4a5MX>>7A^iY@T3=C551bA z*gxlJpf~lJ$ROl(z*}ByH=W<U7u5(HLt0V95bM&JX}xKBo>;?=aQ+`3s0 zE~aU3X{z@j`-ZX4F1IbBeej*yc#!sOeB!ZBpHg)XU#6P3_A=GHmdo_!-FTVaylXF` z=6&K}A)$d7X0)$&r5P=b+Lv~`L8O!YYtrB+V>n3*xzetz;OhhTh(N7vYMWxqu{1#1 zdFqA#(71C`^Sm3s$z;R|t(Ypu+Qs2B(|ht!y?BR3i!ko!Nl+>YA3+3#YQ4=sJGzZn zU~qF0Q|t6U0qn+C5&KsT+=9rG`XzmQ0{_#4c3=lB(;@wQix>Z3|vp6?BEL?;I!u94NRQD10?bN8!_1 z3WX16=_tH8i%>w&sV}-Q=dj_{nxpBZdfa%1or*S|4aSkjYiN7YFbRc$_M~B;3*on{ zI5whfYpI8xLk4*&_2`Y`Cv2;+U-Gg+8w1;<;*Jl* z0jW*MYE7o_ni+IepEuQpC)l z8}n*Lc!$;=%x>*TReEcKReEcCSLv2A3#hdSnwI@E7svi8(QQ_{wYGH^ z4X*NPh^)Lob(^YAx=mFl-DbF3gY#q+1Fsg{rrPc{%RCIHI%l`RrJal}w77o^%{~Z? zX`;f5uTbN&XC>Zg+EiTQ)viszfWf6Wms{jopyyg3bFHRNlgk~yo%+qo&~MUp&T5y; zRRDbgV66_YwzF#Edak%#ZJevEwX2Pab$24+{0o?b^@4=;HVO9#64ra=v?Ys#c(~KF z^PxRrZM-)_c3*>st%`lbcd^}h6XvM7g7$&WY3G@=Lqb=dr%UJ!=jjq!d!8<#m!GF3 z^n&wr37v8twHHCBuT9Owr^bW-h5u$9pqYp#yUPBKDtkDp{C*rY6I`>xxqoG{tjFO%69dk&8|ZhP2*0EG@}f>u_nQP%t3((o#&8wqI+B z(Hi(ZKl-r5r@sukP0ykr$pHOT{+lcvjsox%FLSj770G*!!ArV$p^skLsI zdW@*}0fV~|{~F3Y{XkZA1bvPT{Z<=#6GNYq8tZ1(S_XTvlZ_?BY^HG0hYJ2d`63}Rh88Z5J+qi zMA&2#L9Hd}6;ln`^$a)LHQdNGEJ%$)i((f-Lo&=uHXo-^CEB-m_1{;L>4kEd%)QJ9v<>hDsn8N{)g^8{Kq4_10*uV;ePg(vh;+A?uZM2!oNS z$5fPYu0fhB#{1Gy4rdh86{Rum6#`O`T4tkSKVwLx>1qydjWL)i-m`>Y>{~ahm=zkN zaW_n2{I-j2((U&1)T;9U%lOuY zoLd8K5@Rpk0uJp-90<_^_O)6x%=3%btjCn|ohd=`00?IuRA&{QBh)aj{jNHPWtfH) zna6cD@|MJo;>AI>@~!BBs1(4bLba?bF^}*GfM6x?M%8$6J1aRuhr4Sk4Tcz>ddg#K z=*F|fkV(0|JeyJ4V@UD6cB)d+djviZKhu5|&XAh{MD2JX;d)g&f;fAsUPXiv!7Qmk z9%-sJVA6l4s*!xYKxD6I1Ev2BnItxUF)p(IIWWMjN*lEHQ`udW3ieBtIzF2!2_Gzw zx-*Z2BZ?)Zz7TT;%z7T;C;g~V*(w76{8YwwpQw}akE*n{jTwS=tLZi`d)rtx^5}Jb zLLrY8`6app(^aWg`{h}xRn}R0t3Ei3T7{5OFS|84js)^xe(xfAskLSCzm<%?rK+tz z3rihf;2#p@_bM#jusOln5DG8TXMdoF#EJx_i>aTZk((TiJn<~Okps`t8`;xtWS*mu z|2dNyiI7qsxFo3IqAB|gZuWkGpxi!!VIJ!0xxgU+TG=8klNrSeqUKKP%Ky?l1SyrN zI|eoF7*HrnkHC>HSy3#FmLv`w^JMa(!d%IdQSG^Ih;VJKR2%Itpp92MtwZ0^v6P^I zQnlEfejk-6!GVkf#GP(S&_nP=pq}H{4%A%MySIWF3WcicX7VwWW6!2p=d+5kd#31= z-7!U{?6Xr8Wq&zEr|i8`h_VPJ)nKrwlK22h$?|{$g>!CI10`muOjZTkc|exBJZ7Ec zK%&fn#BdvlVh0j^83`KN`Qnnp+UvOn1-y=kb`7|dzrFQW%HJN%(}o9i+K3HMYp+k; zYW1csPs9FY86qT~mf5PUM`Z#vYpqY5)Z)j3I*c$l(Rvk?x}j;QE za+L@-b#Ye~l~$y1ySz82izJ%{ys^K zj1;dO@g7+z+R1|=CT9YWpuIIplwm-u9MBs_iQ#>1~fsq6Q$`)TLcC zTpypz4KTz8ME)i1LXX~HSm+=dy*=6J724=^cc6E0qK@9bCMxv)I#EaOw-X6HgquPK zAsg$+9AT`>-B08skFb+Gf+`0zO2pst4@2({lekGfv5X$I&Y!4;Hy^hThc|p7P7QCq zysY8PoxYO`Ck42Gpisc3P%V}WWK+nSs><-&OSQ@ej+)=P>1&wJo4D2dvSZl+j?v^d z9W2hjW0RweJ7_}EA}2qqNn)(FiaaCry*Mh+ny1f5kSXtHGo_(IF{Q3TXUY{7I#VvJ zP)s?yLT5^(f|!DEQ$szHme);Waunqmw*By*35FbHiv)Q9>!NI$BAR=%(fq>%h2~om zbTr#0=x9DOL81BB1Rc$LCJ>qkH`SygwWoqH4T?wtde#Jcfus{r2xg(}U)hg(vF!8p z0&YmiSGD!^ctctsQKF}?K&Zwk6^b??K^vz90(8hjq{s-tEZIf~lI@S#WP515BHP{L zb+RSL>twrrydqoec%5vQk0-Jr+|*RJ!@9jb$lM05`QJ)(2y4-v(ow<0=++9JdugqwO?VAm>|$Zj0z^umGLx^|VaZZMZ{ z17K!B8lL$#=h4i+sTiMNcj@@XA`0J$4tz&D@IArC_h<*c0mhe~c3(|43wklH{FJ`Eq!N9RfJZ9_7}v;5s|lSZ=0xHT+sfXWRx&vw3aj zmsds?|Y=+cVVPgqc^hz03$B*0%PfNzU)4Qmy^sW!m1 zxd5&;lc=2px1Qj7)7N`vFTG82dxK`1(dRk}&{AGM*ZQA!Udy`MUh^5ms913a7>%vP;^R zZq#ta!|m1-i`LX+T^pEVJQI#;9+*G|9V5{X=P&x-^0yk)*E&0&_JieP(N5~S018Bq zy&+<+DO~Wtst}eGE_i+=!N2lR%#*+cMt{@oBEQ)5zR2z+}<01|6RPU{Dkk>vGw;;ppf zO2eM~bt?C7Z7E2sC{^)bQOO`qwLuJJ5S2OBda~MQp9fPH zBt@-~|A=;#TF1)IsP)`PW#b7I*ulmlRVW)8NzgI4!N?8>&R~G8Bb8ykawJcWQdbGf zD{Ac+#ci!6$HY{V6z&FOQ_MqTEYI+p%M_=sH=|I*Lqkko6d!*31m7_m$!?gDJiM*? zvmw`NO07YoWVL6BYU?>+_XxEhST9DOm|74Nhr_a3SH&ft8DY==NASEx-Ktb-eKL|q zk_JS#vUsFK9rRPPFDk4E;g-Np(5rS$$BUX~GOVawQyJGZGd-A|U~&#_K|5a|=d12; zPV5K!U#$9n)b9;HQQyRVqP}VViRD{=V)=bPv3&5y>${xg_y5HDLqD;6^e5u)`-$bZ z92WnM`vdGj15AZt9yG|L;}N3{w*yghG@7@Q&5EQi*U&-#ei*;tPoyt7z<*qMN7I60 zJZ#|c5TAxB=Erk_hR|=AJ(zS+gL5_RN5Qv#68uiyqoI*FB8RD)0YNvOmt@jQ<_I!JmqKuF-RK``@hKS!xlmO<;wVWc5T<*lJ;HW~3syN=^T9Wl;- z#BeoG#Pop~?93W~-cwfEj&OL-tQ=I7O$y^l2<-koY>4vZ6KsUmb+av5s&4&BMwTVe zA}*Dv(tv~okgx`XW_Y58ks?zGqDv@*f9Q^r?3M^f-LY`U8q>{Z2$&QTwuV3q)H+Uj z5rWn|B}CbAIW3Z0{5~H|d9;;k`^UTD&yjWB)GSswhmOUWH^sG4x;_i0~vm#Sjc&kd|vaY$tf2peN>Up?B_QR~CDsSMH+8 z3Ia)t^WlY>+0oIw?F2r(AU(H3qB+CoiC*TKcl!Kx&yPyG8Tf0 z>01N}&P<7Az9M&BwKEd_^99=@#DrWaM#qHq3SUu<><}Hyk=f(p$gEb>CM$a7cZdc3 z-Ycuc2&Ebr(JR2E_?pvW{5Neze#|B(RKb1z?=$}Anp{<1x(&0bu>yX8eVKioA)Z}9 zJsPgPf+;#2+o6mrcNy&MRO%u(-T|jgP9f=xj`LGe1wNSAzQY3FCtCIufc7W08)SU; z!J?p5+d)^v5yq)su1AI7!@SAyKCIM-)7Yu>Wkz$fEIYyGO0E=NZsxjkw%13E#h{Pm ztlUGf?Y#NBUq@*m=&3T7)UY^q<5v*1q-P~2>r{Cwiz+YWqDt`p2P8=k`?39rk%1xk z(pj&}YhAkEZF~%WkHg=g&)r5(kaEN2#;yythe2H!|9L!a{Lh0C4t<{G1SWl6CC1eL z@$Ta5Nb>li6C3n84>4J)ePndDaFlM}7ZejCp)EtEcUWOB1GSyE7(PtAJF0??n+CCW zkTMLjG8A(`REFW@5u|QdQnwaK5Q>fgZBSR-F{K_;0(IRH7D`pxo!)>}VTMqD)5Sgn ztO98omNczZ%1Dm{HHULLzK}J31pc_E| zirJzv-zl~c14Cg$2VA14bIq6!y;$9j5?(C%9$r9wqQqC^DjD^mMugb55cU>`jduZq z__chzs*-U!7`;fZhM*kI1!)2lJ-hJR!-DeOe4?`V)$38T`G@OOwy z{l%Fu@H0qw3lnxZ6JEiD|HFh$&V&;&0T*dfcRLf##e@VV+~7>G{s{^5opEu*^nA>G zt~23{e?vkUCX_l8{(=d`m~f0Uq1%2)z#9`%U7QJFO!xvAl=`R3k+2jo#mBBw?>iGt z#}aLr@Pad8E+#yN2@g3FR%5~~n2>ZP{2CMRGR;)2GvNbFz}}d;z?tCs91lCAH!l%tKkc}Wv=U%3(zS&6Z=#(YJl!? zDnjMaKY(g4lpdQUFXHu%dqAL+P=NrOkIanb*amc2y z7ENdNTh^Vy*{x&jmHF(ZqIiUniqy_q_@Pzd_AD~l?Ky|RoXfb)NnebGfPg!S4nxe4 zaInhC9x!;*Kh?A9bMlqe*tGoWC<0!SeeHaw@8ddG1L+|o46|EaP`w)xJ#}9m*_V|x z6h+_L7nMyvzPu4+l_N!Ju0*>L#kgK2p4MHzFhrkP6Xv5Dlt! z!l>{Bm@blhsS7a@srFjD*1TAmM3`-4%tAENn*BxJtSq_x(={SDk4 zf|04eisNpW7sR#<8Cn-sG06La!26?ROmr&(d174ivCHeSVoR|z%Wl3WyGV3)elzsqZSTuY zzi3nij|cK?uxX{8lxgNNiVTPfCO z5qvaZre5Y28zLaNMvQwkIqn$5de=GX{h}Y$i;<~Q@@$5+M|gXQ3eMDn(e_AnR=CCy zHY4ORBYoE{*6P~DLvO^jWz4l@HrIT>wPpT9lUpuc)><`1+}sF_%{OBxY2SNV zYx(-ocng|y8Pbhw<(*7I!J2(;lYO5DY*eAuxRrFETN70jOnUJCF4ROVVjE_+--~tO zTC1n1oAilHPxe)d#X?bcSS-ePwOB0b?yUgS0D#mTF1x`?`)S~R-jC~SQ|&G4tL%$5 zQDF<~V6|_k&5%3)R=%Lh#RR0C2Dh1iA#n{qxM_+*fwUCMSk_&_MGO0J8(U~O2vtmr z@HDG#O89W_GFt-p$fVxAHAdWOSpl?wg4_WvL&01>}le`1R zeJ%nNAb6Hd8WhOp}kN za~zdwrmBiY$oub(5PJ%$tnIydSDisel2BM_j@hH#zBbO}&!n*7qgG3AL(+6bZ#L(D z_`bI-8-lp|`#?|myi+Ww&Yi`5i}n_{T0TXJNBp@RPDXE@|vKQK0cs^ks7XFDboc3?rGQ>9#AlcdZNOC*=UK` zG{&q#uj7zk?VI}2Pk3T->N_#qg)q;6J!0QEl^7^ctqp2f?)IzhS}Rb6q|%@^0M!Q7 z*7Lb8LJyN&{*~xtGFd2b?B_29`ANaI`XEbAz2F2ee_W6u*AwI*Bw`Gz5pF*I^zg6v ztD!>qOZ?)i7mW0;8(KXR16i-Uv2dd+;mq@R(4l-s34EF<8E4^AV+56mG!sHabmN}N z2JxE^KxNP+wr;JaRGb|q%LlSE0^g2^2JKTHROLlI4UPVlJr&2wdlKcaK)RAo2T_43 zz>U;dyq~=?8(O{t+MxoQ{{;lCQc#tY$%x%n<+ELJTtf|%bHhc)rRyAzN1MWUy>U5P zr^5N-G+x72>-n4<5^L;ayoPc-O^5^G(=ILsaod9<-nHJ#7dM*tn?{Qvtje18rs!ia zYdU_?J2mszAn@**!*5$eBp9D{dQWCAO^gY`wtPcs0iG=rb?{S|Q?z-uWf_jU@#500 zxWM$~dM>-afT2AgpvA1K^HoQAKtPkH6dxdvxRYT5=Y2+$-e71AwMuLV8zh9n3%Y+# zM8=p*0F>bI`rsb3`sJ%ZD?gvd`E;C<4)#zCZ(bIklS(;CZbJC2i64zAW z@UI3!4B$Ug9ll24(AF4oEG@Ll9WyNjJs%DjnZnwQGHAeY%;TT(9hq#ag(+)kGoMt^gy8b%MeIJMfvsN;9N_{K3wMuRG$i(Tu4e`-M& zCKT;olQIk4)5XzYw;?rG#Km;ODBM4e#yUh_*4%DvPURn%639`6ajJ^ zP&_jwO>P?YON7y-M@KS_vfH-F zr8QxrPae&~&^jNr6mz7`^whKk8 z(JS~zSG|HicID2C72K>x9Q+b2l(X-9&@CI=GhRv_p!+FX4q}~3TWLa zz$sk)>Pb!u0dTAXUPKttSsA(J&KwBHGK$RT`5WU}(ys%za5qqSQI7lpTrKD%e?aClqaoq{ z#85ICQuz{X0VyFGGrt4%lsZYcle45I=zj@}85nN|n5;=~^`G*9EdU~QWAMxMDn+3g ze9eREX^jXAicENr6w#|LF}%q7FZSr-J=H^0eN~jCu?noTM>mp{h67vH`hCt-yc&7s zpfqV(=>8aK*A(HwTrjZ~3cOn>S3?_KKS>Roh;E;`)bt%9l2Z^F{^)`aBavZaiZ3wSCn0N zmZ(y=Ht+(Dtn&{u9p@ibwk;bC)y#C&g}Fp`kG-%)A}v-#S9~LHT#H)I0Sf6`0j)VM zg~JNBA#qshR;~bSiSs-Tux>i=u2tt9F0LXZxx8f?lsTP7kGiL*q z+b+?B4o)L}4=DSh#+O|NFThT8Nn(Gt-BH0m-5Pbl{-p}`a_M*6sy5!@r(OCBTrS6R z#**w2g~Rf}PVS!OQXZACOECI5MdVAiD@I>VsMubnsI||?`hGKhzp-`_glmsB7?PK^3)3^w!5#(9X z7*}1lb`NiB=n5Z5k()iZue_*({9p-RXZz(HTkUbXLtp-6{)cJx49F13z2{y-jcjj_ zxF3U-R=(qYe|w`fU~{C@HT-ByOW~P^4rWNeG68|Jj#oB3YJpftV}QAv=gR>r7d&-= z!3aXJ14(Rp1K1ob&VtADe!5FRpchcOmD;EfI}BqSjig^2FQ@!$A;V=1aB68EEEY29 zK!V^?x;KedJFUDyTwizB1~ZFy>OC!OBUr>lFPi^X+j)*IH`D~J8_C1%IOvdFzDQz` zxBWEue-Yk98^XeT)+C(tIgkq<7P;L{`ZwT3Upe_hM>lX5`JyXN9gfTpAMm(KFtHD3 z(HQjd%5@_5X$`&qv=p|^IFw=G=<9cPaz-Vq{<6c>@3ubEK1!; zf(pBRbuiQE{TinCHOM~*>S=(9)e+G|S#mv0gzCB_%9`;*L*mO^7^u3T*_p!ozs#;m z(MP@!4D+;kTL;2?{r2|)IcSvYX;M?H;sndLpe0U+ZRTw~8ep6aFn~}eATg`BcW^(i z7OUvhtSrU0P(jM5R%Nusds}P3mXdk2_i3JU?`}=BWn6L8e3nLptYln8 zp{+E?bjGY>ny6&llU|&@7OBftSreDXp*-Ca1t$V?0+(Mjal(TeOr2xk_jG5xT@kbu*s)%FY(IScKv-=OC_bQ4p$aA#n_uNlbJqm?7{GMw+ z7D^7!CA{CyQj&wySpRe0tEU~xG}FkrtoUS`iqc<#^D}Gd_nC~G%Jk->mV)m1hH~M0 zd>Ik)kJ{8e8Kl0bPR7v~_&86di}c<-3c z-q{enLwuhM(WsRvEO6$A>uxu$Y)0R!k?YLIwg2Sgy1ueN6f& ztwnA{SzL9$Qp~+EB2zdJYE60lx*oD~%w*c~v^rzOfBPhva@5ytbB z6@_T6452AmY8IAY3t9?pqrxxjMv(EOl)uMC<_Hyiutu#F;BMrWf;CiV6&3n$w=A?o zWQ$Uv1u~Q<3o5wNMP!V!Op&2P**ywMSVUG)mccSaCpwiIyb6#QPDr>2iD|0%=T~rn zYAXJB8RCt|Ed}GL(C#;=1J!4DAm=83?`5wCj4|GuAhUnP3SfZgJqKdExI~*|LoE~~ zqZ0o4qo?g$g8H7>SQdQ)+0cjbT(v7;ot!j;!1Ooq^yO9WLiZ{-9&%Z~YZggjfd>tt zOL#_+^tvDij^au0d%NJP@LRw@6#f)HNl_;~z0ATt+bO$Wr$SLY=LR+ogy`7Ai|}z+ zi_RYOLDhIyz0NYOjL>eTrx*cwicRmeNE=V_;xcLOqhTFcbTkFch%aHeaB_*X%yUuN zQg=GQnaS4#AL(D2-V+$kB5d@94F5E5ABbE$+Vtil<^X6Xk`Q$`0Py~M7a1PDt*8;u z6p3T>vSJxwdVjl%iY2|fci9aN<*+|G(U)X&)e0?GUc1@n^BWi7p0~XV+@E_rpiKx92X_ckSN2?feC7{m)L2 zmgr4ro_PPZQ$$1mpG*B8B2r%%*`V->j-v88(-vE7h688~y>d8(kb-u(>&4G~x|V z4OZag@@*-Vv|L&A!b1X7W)_)b)z)~ib3};UmKupO}nfrES==i zyY155RB7+{W}1We&;adg7K{)$_zdf_BVC4d1pt5va!cX;cIh`#stH`(=I znVLDeiLywBgo!f$wOl4jC;Y(a;}p@jSf=n_7B{Yswd@fR@KJ<%KLANBIiG^Q*E-Ii za`{t0Tj573Vh7#VL$^5u*ndDTvXe%_!=cN&kzl3^(?@W`4c&O+P( z+*R4)eRB4p%=5iPe+^q3f8NzdABo$~W01Jcnb-n}-0-Zvfd6va&xy~f(GOQ@P5m6Z z5IIhv2?b}*Mmj(6D)f1J^9m=_*4CN4O(BLEV@BO^>=kM$h*0iDkb7$v1C5niKRK95 zO?R`hh{=~6#r6hJKzM>onohL+HOSjvgPb1+2~ZIsxe+2MCnCc09!l><@dR?mtoIuY z;a6vuk~j4sFis}p;1Grx{6?s)*f2UE#A1SW3(b3?P&LiCqgja5>4;Qva)iN<=P6=F zix@zjkAIVR91$1o6FbOJ1yic+gUh!>P^$!*aUBHgDgWj(i>*b+xar;uM+;L6K^##% zR<;xz3$v8+EiuXGOySP+lSITex^syyOj&ZVDeh5;;#FrK9^{p-mV&1V*mMAFVF&(GwsG-@VszMm;P?vsNVO(NscTgxM6INeK>Z=efz zD5EKk$^mb``YX-dLkZf(K0sU^OS&~?-Mz;pub?G)4W+xLVjw6TygQxHqw%vU>XhEM z&atP z?JxjS`xfu-G`*!ZR?Wi<+JI71Vz8})S8sa7H_VvYhDjd~itDA9qNIHOGN`M6xp`Fz zGdzz+)=|GzTZ8WE%3qnn>;7^u!;w{^4B;|rDHul}o_aYzjv=hd8uJJ>Up3#&k ziS?`!l%SlyxWLUzEQmFh7=|TIM6y-WxgOf;QBXw1&wN?w$t(U0dU723a0<*Nm^cg) zUu!C^^-!BZAuwZ_iep0!vAl&dNf}!!7V$!ACaQMZQwzu5)|GZHU_N!_do9q^>T@Tj zAY5n4{54%^6EPMm!A7p(cFD#*g!fh_nKjs0Vo_a47V+dLGQ5iE<0#@^nK1Y@=$19b z)g_!A*=Ftk2N|lzN!}FALelhp3FvkM(QWugKsR*gh!s&;8Y{IN8vL83C}9{&X<&d@qAjFo#uh4q$HXv|5{7)Pib3OZsgoC?~XgyvU9z zjI>U@o{Lj=fi8HLNnH^8RaO`5s0#SO0q-kksZO__WV%V*lu!DJcPsbLilxmKkU8B) zB_!Gg%UDF2uCPz+@CeNUC}N7$x6x(SfX}hl^?`;p%*2MB0%QZtT#{!ak=Qb$8`zz4 zQN33ldq4M)%8DTAfHMz>p2+x331kWb07(r?@dA^tDvu@(MDU8=H6rIU9Ak!2)tg_S zs-JcnR$Yd<;-Tp5HCd2i zh{Vo|sr`&ZiD(W|5VGO!hh$>_{%_nyb;KqDq@~#T*NX9j767V%Q)OKtrfxi@HBp-P zsjUG8jB??PiH&_+wB>@XuO|8PuG)%z`$+FW26MHgU?$;o|MP?s)lekT`vWG9*qU`Eu>_NR0{` zwgfnX%g&%d+2fK>Xo9OGpkfM8^J=>#VS`%|a!T7nTRV}qaQvt&X&XXqnX(nzlAfec zKyM(i7;J-SMreg!&L{*FigaUW!Y`<#0@ z+KlIrF5sRHv#)}&hsgY)&6dAu>1x;;q;NXjlMP1UFA7qK7gGB2_jA5X;qU%H)*fz` z*kk7)3-x25&yNFg8v%(6AaZvYW~aNOLzT19Je7z`BqipHZ|N%ctARCt8suMogdG-J z5owYZ5&=_eAw#o+K%2Z#_%)Bu&@dd(8SW%rUQTU%wI(;iJF#CkP}lYLoTwz1Zq#b$ zM&Unc%i4SYa6gST@DN)qbgzGlSpRwKd-6IRhs43R5NPd6l%k9G{{`b|>R6XnWW82o zXI7CmEb;;t`Io`niI9qSPkjVGsXvJR5|JIJRDKA1P9E{jVa$oz=iel3GhtY65}J&E zr-ZHFoXy6M?9YsVJ6$d8ta`mI%^y=+Duk6%@3MhepIwjxP+fnOuchGj8K|e0JxhA3 zADy1U0mZ-axwLdtWse*3$=r~O@3Aipah zkgo+|J+wfyyB3Iav&-WK6Y;${+Qt5c0Ww}(lZ07ga%OQ=1^gGQ011quKt@nYltL&B zfe=fz0B-s~CEN-mc^)qn0`eSxLodVnZ!=Ciy#3%CT8<67bXM*M*lhoMl&6DuzNV$% zS|W14U-QhkI`MoyF%-RU7tLV5TbR6Xm13bVEas7)JR^#jw+EPCV+qu5JHC$||Lik7 z*RS@!)KKIygw=j&DK(e#qs}onmmKijt+mD zzNNfThv~bEifw+H!NsyrjVV+wp?tSK?Lak_3)K+{)p9Cxv4pKq<@gDVYH5zO3C7pq zwKj3JT_JZ0dz4J{!ZaX;V;b@Q&K8+@nGqc;jXR3T8o|`8q)HcU%^z4T86tOJXG_zJgflCTnLZL6PjAgsPr1F zkLmiOcme4}oK@8x#0QI-ilh13+!z~XeYCPGji3=b1OHn;g zU5PEF)N!Y(7_$Lmcz!k79<+#lfEnjWVjgSXVwauPQZVLRY;zv8*{(A_5u1*i74)WK z7z0B2NA#v#{3;zArB-8t1;&}$3^5*|?eRIGVOWEPL2iCP1BJ2H@bB=%Nx>Fcrn%@T zM3mtAoBoJwlT44#G$oT1E<918ov*+;40Mjys z|9F$k^J7%(>uv(sObCC!LT)Iy8pLw_+3uUqtBHOR}Op&#?GJe&UPJ_Cmwgld$#8j{))K z2$o<5#geeKZ8@_9Oz>W>GfTqOzXxJ6>&6%GgnHq`$9SOuYqj>g$4nv=sGhf|o*>q9 zP%w#do_Yo|Ddu4&#i+!IYJH}Z@F@5d7615A#iT>89n7SjA#p1>j=brwLZUPaJX`}k zejR_0eDB9dbk`B6yB<}(_g@33^nBz~RPafbCk)q2qo?YSgn%DWvaTQKA1Fme@%yAt zCIP(kAZzKnH2MuBV@rqDQm`BHS$`kxCdkAiVEX1bF&&xsW7fBAet$Hw1HYq^$?Yt0 z_%8=PKf7M>vwWxI=P^gx{2W0Is(Xa_iI6PgUFK&*@$*mxW{N?k)Tb_{7Ui5*c6fdY zV*Htk_j*L}^Q7MZKiBcdK8;-1U#$;F&j6K-d9-SNbvjoQ71dDN>%4TUun>KZkay0q z14h|OAV@Z0Mwd(Lc?vpz-=AN^FK%xb6Q5xQ)~Bkr2@>tuT&y>~BP7At7@G zAd|jRm)!5K?No9*m)|W_xGEHTTCR^4ouZ^TTEdcBT4GDF8qffvh7zf^M%r_W;80w7 zvOfPBf^uC8;{fkBCnMg!dI$vceIlzE6-K?CJ${TBk2zOj&W(m)k01ArWf_ZzWw!_| zyB((u9sSF({`%d6Z1)n`fE`!Y@=|q)Vn^0|n~$-fqjCuvwGrGFVd62iPkQqvn4r9pgZBx= z*uA;A;ZcKT9KG4S>BS&#Sy8Us!4#&8x8$x1G_vm?M29`t$v(})>$gM0JJoL;bXvqJ zTB^*3g|A4n;jF#}>9h#o;wM}le1LTtLb6KUWIQYW}R4qp&dN#fMKXrm`QV7DuBrIS`Y3hS>e<2MH_bn z0_d9N!gBS9HjG&AIlLyyOQu_}950Jrc?J^c$Y0RP*LA`#px0zJ;PPm)u_Tx)%~OeK z6+t^LYdLjD*X$&3U2lm=djpn)e+`|lxN?0-#5hxU@BN)Fx*l(n=yoDYOTqu0j%_>R zerntOU2J%A^=)3VvB-hCg<7Ak%98Ix(?u&7FbuoA$x+G1XilQwiI-&KjAJ!+N!QE? z8n-HgY9Ybq7WrakT<*#Nwt~RUInDt#+yQLWu{pqEHtYM#a)FHy*y`gtEK9$N*|cR> zDwfxb#O-Wl`nz?9S(zTHFTOIcR>7&EWyq;J*Ab__^6(lkEv$;H$>u&my1=4Yi;O0l z@uDSd&D!6@J7GIrx1OP`*na)u`8MAZ;0!K1g9e2cyvI2~?{(SraS1aT&LV`y-JqT^GIGSb zTL&UG-+UhB8+uqWLX^upbrT8K+tBcYn4B{J_5YpH75gjWru_Q4?Fy#g!q z{){SX3rY4?;Hibet1#9qs91|TdS1InV=|3;ZPLmh@)s2J5NBm9^KvzY=Aqll=w`T|4}qPPZK7(6vvGL2TYzOC&pm zYOO3T$?Cpzl-kjEm2BV(D^5YIC?3c1gOE;gay3EM^PYig6NeEBT7dvYL$(UAKU{j{ zC|a}=B1ni2AjH$lawu~e{c1?-ZWC$Giro_J3oyFzHQY3@6_*C^T_2^I>EUsHa2<4m9gr((fjn%~g__cN?~x!Y>7yYy|7;BA-%Ub=#dvw1zP8a1=-8cI zSb_|aAfkSYxZ=~KJs4lz6~JnnxfK4e02wSm1L*>ko4QcyZiabT7g7)yf*d^-4+LUR zpvAicZ{ajOJ82yVwU8grjEy^#kr7Bz`fVw=h4gSG)Q{Ur@t`Z7V8z)6mg&}`s-Ug^uXYvtq4d?Rl*u+JrSEI-}YPrYTSF}7}f_tsUQ|;5sH%HWMHro)x4HaVMg*5F=9SI>SRJH50N@# zJ@9AFz>0OU|sPg2I;w*swxZv3#a3SuId95tE3H(C!nPz2*>4V_Kk z>mh6UbUdL~tH!rh8kSoMW>SvxF~>j%E~Mb(R8T|Dt=JA6^b&0YY4l6wf2)nW zG;qSmyJZ%Qyg0I6I_nbWKAP-P@BFw2RMCTK{Ozqs-*pr@CGi4HvS}AhpUL{Mad7Zj#-%$>h%@>feamaRZ% z4h+#Ya^&4V(C)gHbo%j#xtx7upePDI#h|JU|hn?TGahF*rM-(2m%E5&kB&qeNSqpBO}K{pf0) zJBUxRf*%>;n6(@ewqw=|5<7TR%mW+~lra@%^M*loT@_}-dJ6V=9msIWNF>9JcxgtC z%M^Ay?t4OZBH-M+nQ;g6+fUG%cR<@CY;TEv&FJ6^*Wg!yxZzCNko#%%o#|ovFlnGBn}Mcll>eR=3jZTOO#i+WwI3VgjJ58xPEZT($ny1 z$Ow>Y*4+o``QT0S^T5n)d;osL6OlSB*_70843fj>2qf}=B+21b_$~&|cF%(25r)m1=PSZow z5_xh`GJvF)&qbnnauU^C+ANoy2$(G!w2$IATTUL^sL6?vqx8EXhtZ6$jZ2x~`R*q- z1q`(>7V;dOCcR7JD3XyGVAcUYXbWTuq))b!DDW4}b5#w~+_`TzT3*w;ssLk?xTHPS4Yucu@4C zgW2aC9IHl%D_;3nEIgX#8gW-E-}IU(d}~!e=>kjvE4Rq%_E+?j#!K1j)ZfH2%jE8) z>(9}RO(M}l1n{59pTwnwqDFR0i=(Do-KDE^f0lrZ`3Ukz9r8#U@<;($>>8yOv>@3x z{o6zPUcpwxmgZa!qVpa)O?cq-KHDdt&Y&8s{T{&Iq<4H%fGp((!(I!amBE5g6Z#5& zzLFXdV&NH(Dg5{mvFD*Wj8Z-g(o>_{gn9#Yg9DMeeE(+95aiXT4si)(9fDcAqpq4= zi7)$jUrPk!l>$K_yxxr%*HZW%{+I>p;K%BBh&FE^pke~_5nx95qrqtV6lP3%@1E0*!wVpPnELMAI7*kfa+pOqni91SHF|+`tDKfoES9;bo|a zvM(UOhe=b7Smzs$&|%WOjZ7qEo5MV4)44PcLW#BgkKC)FsbBO`5{!M%^wu@fOs9Yaaf<`CvvGHNbvSNiWiN;WH@d`1;JClNQ zWa@MZo=4>L9!=25rQu??1N`7iz&DQ70{$jEhbJN`;V(W>1aN&LK3)XcFmOrw8WBX1 zi%T&0Y+C$y5ty?I0w<;?ftIc&;j6$elF+gEMUsv$h~t@BBTX0Wdhu%@e&GUjx;K7x zHH5COW{!BzX$X)9z>WR1y0XRlyCczF^^R`9W`eMJhrt)FU4hh1ML%gv!R%p3kBN;W zUOgL7a<_Y6{`D|VwQ8b#@}I8Xse$~zAAny0DEDtZ3$l8D zb0cHIjwRFke;6juiFYG>vg0I5RlnXqthnPwW^58K9b)msf9WHkht$4fVYHB1-YY|2 z%Zh7(JI|q5K{~x&E zYRXOKMT@r%%0GWJHB(&gJ!A$RfjFviISJnpP^Nr2%6Ok7%{aUxC=_6m%R7id`AM2- zc>7Vv$D^3H8`fn;J#_w_swn77=!R~{T9uW5wC`sLJ1<}M?JRo25rj&jpGLq?!zt#tAB zn=>dfQUN&P4bUK=_~VM7F23CH6UA2^XR)4P;DBY;)m0xpftuI*GB=>}ApaUD@*`XopQkfdD4U{AY_WMI<& zgFY>D>eCZ)>C+JFQ<_zQ#N0Sp3n&eW5s~~%9389ZrFa?RgP6-@ zAP9lkGSGnDm2@p=n#fS8cdmlacon(?LKP}>4umGD5Zb3%YIZr%`;~#^=h4s%pdar8pcCVE;yf>c z^Kuxk3+}?m*?4#nb4@k#w*x1ytw$NE*b~S8UyrvI?S$4B{N+TfbM?=_uDJ(-ACiH+ zoEAV=lcj~GSz(k+vyRgantw_6bft8?C!g%mAHcX_@@;H=QHneVBEGoePYZ zCk+(}@O@LX&00i3)nD5g8saCXj&zZgvEu~hcr?|QBeu#2(h~T(TO{?JK}nD1NZQ9q zcdI0~N@9PLcbQ7+qLMap(n3}FJshz>MKp87RUHeH(wLni9-o1~I7d9_eD8D_j|XkN zQ&p%KLX$f-i#o$&$BTHmK5;6|y!O?Be!%OBQn;HNMQBhab1Obs5&LnHcVwPJ^19}A zB6)LwTXRsw`fqxKdB>q9+@M4u_+1*4U;d^zOWz!jhCbpGgl2&F1Q7_bK+I_{F#GW$ z#9}xY1@Bx5nFMT<%s}>SsSHIh)L-Uoz|e27a32{3^0@Ru`Q>jqMHU1s+05sV#}V>5 zLTIw@RgFfI{X_VnX9`6W2>Czk4A9Ph+97D__jahk-_#xPi?e_?43RQ+4M!|h5wker zY85e+BkEMdIF6`S5kooR8Wk~sBj%}yZX9u$ieOijw^~K~og*$)5x?VzSt>$wr3+QW zvmEi~|9sC8Nf}Zk_VyM2N^~!Er2!R>=guW>51|y zzJ$L5ICH13pb?+MUtuGDX8LIUjv4Wb_^aB8&*HCIFiMbTgC&aC?4J$Rn|=LYz1hnL z>&?D#u-@#(!Fsb3gY{;w9ITqnP5la|ONIAei$)#L8@vCnu`gl(@+|=BEa2M@7eJR? z&}Hd$Xj3eJl8bIUm@%6ggN@S1-{KwZz<-Pb|I-}!mpSl1!-0Rf1OEvQ{HJE)Ka%kO z2v-Dgfu{B64SB`}_~rA~6`#6_E}#H=hX$rP@;jr~JGaqh&M%5%}+1V9TOTZr!Ao#esH<5h?f z6og==&~pvBE=y_2B3^(gW11)z`J4YnVzT+_fN*!1VqqkVU*SZls}84Vmo7vHLByRn z;I6}Y{5c%XOB@)qyoe8dCw6oLa8D7q8UUB>E8~&2cTs!{VLxPkzm&^_DvtC+h9eiC1qcj>Eg z@D7lOWeTGUJLO$}oH}raI+L*aY5`z{#s}IfxUVjc=63i)TfrvVfs^AyRUkYj?iT^v z{S_}uPY00w2;_qRGJPHdizs+I1}EVnPBkJq)8xDOdr)E>CZ2$-t%3MC5Pt;4UxM+y z&}f3FAVr-Z!DB=cJ>`nB}o!lrZ-nat6dh05pe3(}% zyJK@{b1X{1b;lv%O^|~gcmYeY3QD8lR$;`a;-rd=$SS!?Iq+~b&FQ2jT>pL|JsJ@I z%at$%ZRXzTeep`Y72ek{tzo@EOABJJHC8Qn^Y>#B)j!N9g8!ESyXWKNZf0?a9u-W` z<QyK%Ai606B1#M{g*u!IfIuzRhHa7BogyrSF7cs79L-M`)Au25!|E z-`b;#!B;~AWwWn__U^0Ug&?|=_ttM%*zpeH=xlr@AjHp6o8ApI*x->qT5Q34d6uC! zDPCMFBIroj^WCVmxL)XsbftFVdtO0n+Wt%?QFcZRdLJtR+WZ>rLC(c!O^*-JmxvwPD_QPO(-{0X@E8hR_@2_2e_nQYsv~5Lw`Q=9a zA_RKIq@eF$TuQ9I$!R;BLiw$GfQni)zBmXbgIVzLAS^WECVp-(Xx*j;-a0fj9~#q3 z6zhaEHhv@m{^tVQ|57AABd+cH0zLM~kbC<+p9)3u%pEVw{Ti7KfHb9Ty@^?|PypNJ(dQ2BZyFEgjrhu%$v7rKbyZ6h10xDW2iTWVD zVnwHBrUb30jwfC@@N=MMKQxIY#i8Lk6Q2v+avuNl;xjVH`dJix)vmDh&2ff&2R2-p ztP0v7NMuG40w!KbSMHPFkz{#3_X~cXS$xyB94S*d?$gP2-*5@k z)4KmVmsqq&(7|y$L_@EagBFPq7ZSLE*1r-rtViwD9Nt`lX66FE;%o#02PpM09t@FZ z#Ot*~3L6AVBbitY)>xfBMHYd{@?cdYn!5~nJ}?5y*H0UGvX7n z0cO@Ha!Po|&=RmT8U;QT9;1T3sl?Tk7%zQR?qDn@j>R2lR>ZN7} z>Qo{N?~R6|chtGlm+NF*jPp5R9?wjV*J-?nlZc5m=^-ej)e7tp9wkl41&}5lOopU- zWXR;6i6-L>eU<#P-N%{uF`Hcbb#uuxndsam@49~q4J!_L5OIX`m9~qmwj_OFMm(&v z8%bYyaU@FP8pKksMd>?AMQ!4!B7RGzylGqzKZkOn zyFe5gNZXOTKLpfT8zM}?^s-CuY66#`+r><`4PkH5U|ZLY=PN*}qC6nT)Gw8g$_olQn{Eh_9gPb7tnLhHO(wWDYY;2hJ*%#Cu-;Eo$}W;aB~x|^^(F?4(M9;!I{&9_t| zAHzg7fg5 z(VwNd6#zK;IId4+Cfv%utY%;FOo&P2%bIE;2pL&(z<1wFFPx=9Db!l|9|Yg z3w%_?^*DZavl|vj*afl>6>!CXtDvqz=^~_TFzQ8vT@iKbqozeMKB|#yXtbz_8#L=> zl`1OrQSnW!RjaK8iW*P}plzYrO0^HPt-b52U#qR6JoY!|F>~+T2cZ3b|DVtA^ZDiT zfxUNT?#!7pXU?2+=FAx^4iqh=CqY`rg^{!Xvn68omXS|+9KLO;aae&!Xyh{y4Xa}s z_+qo%w2cP|m>16i!Nb7v62nL;z*$ynv<=ZrUc-=tQHJI%sU!J{$CXwxoM?R-37G?a z>C$9yqNwggP++yo@htK#l__=zeGFlQ_2qKl`A~5k4F$Gq8pRE885~$Zf+X36KxlTn zLg;?#BcjRx7cEFNe5toT!lyJ@90G>!Nv-o+sR3sjrR#4Ztu|n2q(Aao%#&{L*x!9Z z;VR+Zp=t@pT0j?5uTYHyV{iIa0xr>nE$8F{d=;{NSc5xw`Lgc>EHn*OsA8RAeXs`? zEAiG;5wrBH2yw17i!LxX@j%>cV^)|Y3sB#7L43uu49a5Hyo&pW_{JZ70`WKt>v7Mz z_k3ONmHW$GjwhP7Pc4tk#pd^KQ` z3Es#j{&{{Q4-)YBgE#bT_u{QVrVlSH>kyjO#p+DO`Kz17kNMys1MJorkXga5R_P^v z-%65btHxMC&Ji|O5M{=?SSa$y5f_Q9@WW=JlSY%g1QYV#)lz`(P zhJy_y1V_v~%0qAz`TgM%W*%+95fyMm%rUA3fa5%9bTGjYAvl1~nLFOYQZcQ4fr6uj z;J7U`z^+s#YlsV;3ENQYoJkvZ@I=tC#to~Z`Q!H#K)L`ZW@c1V@^(S<>h};JT1B%U zNSYT>DP3#7LIHFk0pwRB@#D+PmZEQiO49M`lInm|}HG?!(0B$7>LPu3a&Vr8VQ zQ9C0rk_WZ$4Hp64Oydn0(9Buzd4CKwNppIZDNWQH$yy{9MIx}1vQ=-ye3ua-H7l&@ zUnbTY#h1UEJW!(EZKgFsI`JkOXW$&c5|i;Q>g_ZwT=RNrBQ>ku zxH&~DrhBu2>eX?SNtY?+e?^D>BIe;53SChW9R^Y2v!e&#Oo|kkeG9&=&K4NhRer;2 zU_TALAO)`RDNHXif#A+X(|ELUPkvUqqEs`*?KQ0KD^=e_TYX!+U#dO|T>;AGnkrS_ zpZ;mp7yokg0ZT2aZ;7qG+Wn}nSl<*1Uag+$k4)+#-QzL%zShudR1T>BVN#fDY2Kx0 zqS>+*G(e})QMjKpfCx!$@eE$QPJ@$`-tWOKPKkXQTtDaIE=5m~y`N6XF~j3yhk`tT zO=vkdo*5<^PnfIj}w8z8p{UUJjqN z$f!54Y{qKz3d?K{7A26`@EmZ95Ij@sM&V=H$0I-+&yn0~teICs1Feifm!r;HBG^8(7QWw-zF%VW;BL^vf2ICMK)Mf}f{Vz-Zjq zD!#80;8el6Mn};dh+N(`iE{ZZ$+QcOIEO_yhEQ5;x)_YAwsFkVP~wWQO;CJUMg6N- zmwlAcughbSWDE7wiGlawz=LtmM+5KUk~q}9w##%wsLyEEtXgm?zvxC)9c>L)wH;?Q zj~CYnO&d@u%IQ_2rm6|+Ky`sDjVrcLvX~X?1pv9>SQshHQX& zG5bwYX;IYN;NXBWmocu~u_=aEnZHy5c9uS;D~Jq`d<-B4D9ygouot zFxJn)NfQL=esH^h@SxdVYs}~bSo;b8Rn2dR&gSOlE>Lx1Ak_b^&O^Ttbq>n~qOE92yCbSH_`soz@xe9+VS`6*8>JsbunA=#bTC0V%w)07xNs6^@{w`5GEZ zI*M&yU+}6y+xj93$0}h(X`6subts=a2WtQt1FK;>?l*-}9n-Z%U&qI;4v_x?ZHE&i z^K=TN!8{3=LRS>8p7qHFa_Wg#hLcACF7v@57w*cZy-O?LBvV@apC=C+`dpf$Xru~g z3PiC~{Tc90vdXBQ4G+Qo3wD*czLWi3#$&P83#7jbDjP#VhbpXJ`5PhPU^f7qC-5so zoWC2a)$r&_2H>ZH&n66FUM92#@1yR3*6;nf_;)hg8FzuR8?m>kN-r>MN7Gx>& zO`MALgG8+mt}0cpA+iKLRey$Hq~`&)>Sw6}GgN^o2uceSFsk1caGF&iBAK|>4n<#g z!ADT^6&Do!9u&<~FLcZAa$dauJ?HRMikxqwN4tUo%p?liq!AYRtCLvm_<7|9w2+HH zJCo77LDq0A*6{v!oxV+j(OjJmR(-dO;9F3Cn6$`tcdiEEgGlq$Z)i~UkG@-$+LV7% z)S&YKArc|)_|C3;=|*k(mS_c|*))6?!w;e05RuVrNZ_S&7o~FcrN2bw`~spHAi!D5 z#41&C#RABbDrb7kX!QAzRgP1|V7`-F6XsLfmRnq|Mn0|nrwil1H;cB)BV2dPwSX;b zq!_mOA3rIBMy9I-E16!WE>@U}a~L>`Sc)30fxM!#y86bt<=uhw;jCJ7zySmH=9}fjpH%vEsu_1L2`-hQ;Gz^bNYFs0T^-!y z!Q?{#;OaD|)`FzH!d3eI2_8E3H;lNY0vqVp;HBseCTDp#f2YdBONsJ@R{jvstdEE^ z?LnKe4~HC_R9tNX(Oo7tCO4`eXW>BUYU(a6x|VIv=&ZdP+>tzWxxunNXc_1+DVE6^ zkunGI8V0}LRqpxIJcHV+_0)Rze8HYSw0r(mLInbbRb^l(x~fbpK%W<|^=r&TH_`%cmJf&mBNf!m6}z(N?N*A#m}v6W!_HdUJH-6$&6+J`Ib z2zuy(hH^EWl!g+V7A8q4gMas_o*}=vfMvO09dl!kqhA@yxrt(kd!?)H9GU923>(=&RmX#*`M53QJ72 z)Cn!2_A?nv2xVyO;=XHfk&dN0Mrm-*dK1PT6k{{0jSLP(Y*ZTbiz+sFW9C zReWd$(GNi}{N2lBwixqaGBUfgI=~g_Y)=q)m7(#-@j&`}=tA}713V%pK9wHZ1{?H{ zZX};vsLt?lqQFJo`lgA$S!nyFi93O4ZDzDKTRn3OYl4S0k^QyMO=Q?={|&wDO&FoR zHP&@F7Q+q|vpl_|t{Y%s58z8T!JtEmSR`Ey=0%^tWM?0q6b0(n#O%7l4Y$g;315)N zyG;iBA!GTp9uV(Mw)a};4a2Cl`zELQVs@`BOf!_rT%?$G90cid?5r_%lgUf5B|iArby@D5Jc&b$!T3B3-Bss^Xe;%E>F+d_B@&HEx5Pvx*($udA5Evs_WphSp}mNVj>cs zfe*x5&c7}M8$KPd;j@gB_(p@Hci_aw5UT)y7 z*W*#VP9$qvw=?z1ttA3hG|^f)tn(dJwQ-dswYD{B(4&Gn}srn&%$QcJ*- zV4Bz6IGF*DVkXDTd;f=)ZFyQ{pvbDrcHk5Sp5IOPFEvE1?}2}?OD9}f1%$I4qdgkz z4`0#M!&gmq^7z9q8V04u{Hy@`rL-6tKSj{T1u?=#?v^j}X>H-B#N}e}hH4_Rim2on z30bnk(XkFac9WLR2q=9=;dDgm?Ol${b=%$gU`NGKoiCV( zX2*;9FGhW?);`ODppgGr@bqk#_&-gdaY;;`9j)#qf>v!Q4u45mI60W5@pNmb^hV4{~&w2xqq-&ywNSO5&ijYX*z{&cdZ}mwyvxLj^JjLE%yEuMpInCbKju{i2I) zFuQ%+P`2OMIP98Tb1)SLB}SBAK;@CC1hRL^^60-Z)l;|dVAxMn4K#cNhA^-Nm;q=R zVorO|TwF`dppSRJszR(8A3;5BQ|Yt500CTun+LUIs%Rgj643eHw{W1UHuor|=LTdq z?BPu~JJL(JMj|UCeLBKwoR7ToLN-MYr-Kink%kQmE#bDxNqxETxgaOjV&eD7n&Fq| z00gXe8aB%KYvO)j2dPE(xirVz=};GO&4mpu5CmjkG+jnU6QkW>K9%1Co`zvE42)@F zsex^2K&ia<_2`E>H4c%x||LuLh){uHT1m4S0XPs+5cG>k@1Q2hN;oaSk3b!mJ zad?O!?BW4DIM56dVVeik*|Nv6s3fmcc@gtZyYlQ`OWQtZ=SlF%E(B}BIxu9$+oqJt zNjFL+l;%YiWdWT{_Fx>ioR8^R#&Rj5sXeGwJHf<2k=;ZU@rHB-*~$iFgL0?0W&imP zwoUXFmqs0;x0sFIaK&_Zf=xPM(k2Yr&47jQ4DDl2qBl8j;7PJ&+r-O-6QIm}xGRxS zc|Yt`{`N~DMab&dQ5@!9xl!WY=z@DUG_6xK3db1W`btE`V19u=gC0dY)8!}N6r84K z6gIGaCgjUOVs%+JD{ONS4sgeIi;M1^qA!=#_2KUltifF5LvLEVI6zB|hQaIOa=l#c zDJb_+4oN(g{f|pA<_wb{nZNrG z7tKuvB2Q7rBCZ3a19&0nV38~iCuiu@pTb+>4Ehup9QA$S1kuEFa>9-RXcUPD z3+X;a5S}uL+H#g)vZ#e}4C*GH*tNQd;Y7@7J814fN`rB{k2?fG z4fsY*U)e$bZI*9CLX$S|O30n`s`4kmodL%c-HtQ7tN!WNDEt7L z{Nm=-O}Obe2<`0IS2QB4kffiG?d?rlef5t|*p(+dxsh)0Ec1B{t6hw&78M|(*&O=<)gf1j zL*P2ZPA=F11zU+?;F`1S(;{Q_wb;m1)yTb!-l)ze2_XY;vXs~_Gdl`4Rq(87C<|PFHC*{<-uSlDm^&0Vlg&UJy_mKsqL$8z z0AgyL57{Yh>6!JrE3I_%B8(kHcgTeLJ0a{M&f>3=V8GpsnNN-^UCwVypccK8Jpo>5 z|BKBO_Cia0->nF6mkLGt!u@w|_7?7bj4*^x)Oaj6vP=ejoIK0SoQfAWvfD{7c8Km@ zTR{p(7}bw4Z}OW$P!skiQ(Yr+%r~BK5q8b`?Sj;9vO!%&9!Q{o=>5x6N*;*u!Fsr* z&fMUp6Ku4f1`ex+_lbA>C>OwG79cL5Dj~Q#2IWQp;+LAOibHohY34xS-Ywh+d}Cf& zPy(d0b~_?4WgaXb)C95mIj|hGsLkRGOv1l>QK>a$yd(c8&;+ZCy)WxA4<~s+jz{Fs zZkb5I{)?sK(*MDw0}xbl{|sFt>L1_k*I=Tg>K_nKc|laO#PcJVS}FLRc+idN8zC=v zKm*=bu@Ew$v3_rx_1J1XeosE8Y@6Lqe;nYv#6$t#5F#}nyfwB9B_yD)G{tCb9PIDj zpi%6tvyunF&kvFiX0`D{2$FUkhUd&~Wx{PGKA7=-^oFD|xu6Mwv;i@+M*Is9OWgc3 zmzKS~@LSKe{rUE0@ony0QGDEf6+a(}A1R8@->>2kQ5Tab7^prCWdIm`j!n3Nf*&MUDC36*JJY#g8W) zRzv7d^PZ~0qHZkOSWr}RnO7DS{p<}WdO$(ZPR%^A%1P9BykCx}9bAE?r+4GyswZ(s zN!361XCQJvF1Y3aCyS-_3d(rs&o~c=Pn_dMI?h1hJXw5U=9(?DAuxdVDv>Texe`91 z@Vf%lbAjfJ>hs{6;6Llp*(*T><4_Q`lB;K6?$&yoM@Mn>1k93I0+@FYC&5~(Ybch! zo9e28x-!8aWqtZ5$m*ml7iA5jthX@hLdyE^PnhMWtUk;-nX=xZtSZWS7_*M1tc{d4 zl(KHZtQyMtC1s7EtSd0<^XZuN0A(FSS#vS#FO+o)WpTfzV%Ce4wdhawevQGbm6Ua{ zctK~d)v#Kc#|;AenjjQ2GFUtvq~nSMnq5q;r-S(g{+MdaX9g8g+qyphwf%HDQ5&YN zh8W1^wt=(~wBqW85jKd=l7gg*XF8*$a~m{s1^6@H_amJ`hWYc0WjKzY80M4SvJdma zClNixnV?_JB0;wl5p*ee6`e@b{2%)Vn%prl|LdVI{>2YK4kQWbWXSwAM+jVA_6?{1 zoS(dPM+-Qz3t5)cwIm7p`qsC>JgQIXBWE5_Pu~#m?F%(c*f?wJ=jfj|OQb1J7Tv5E zLmU+Rn+1d6`ky;d)Q@q@N%|mLaR`@I#h#veP4!^$bm~D`(=^$#Pstl0tUFmPpHn-g zVaWWWf6vy;++-{3i1x$yCFYh+cK8Bcfe>2&aI_bv|%Pzv9gef?bv2x zVsiy_*@v*o`oC@iM$_tCTO{Sj6dMD7cRv1ixyk`TH&=auIY*h#H{#?v03#`ikva%=K@AZpg)5w1R#k3O@rQnTa}N%^n5TZZz>(?6U^^dV9{ zd_*Co)kpO{C4S9?7yzLiZY#$FXzf!W5)3{aZDxN6ud}!|0JG?i%{c)Z)L2exyWi(O;} z-H326t6R?SBM6`FR*t}UIU|fD+$avwW8oqhbSH+=@Rhl3rz$<%MXYND^ffshkPnYE zZ-nI0jh`dcgQ*Jg1nC|uy1xeRH_w2Yzg&onxsgp=*p_k9N0r*7P3Fd#Zq0mfCSvhm z!ASK#0JnZ@$}SXEp#!TmfNLr4Lv+_|@llguuzUFEGCxp1VQ4TI8+IL;audYE4U76j znW#B~+Bjg+@2J8VP+_Ke+wY;hnW8&j+@czmN94M5{f^Rxr$^KP_K?d|wU<$~mqEeH z?XULOtHshAHI3CoumnP_25l^-**e#&+7&7wo4k=eS87BdD>R-Y8cz~v>Fu33)U9G# zwYrnl@Kcej1R*{*Bzq#*Pu|;uRv@%&bimku`yCv6KyFEI!cz9{gwhMp=bHEzY-gvX z;_FTh!(UI5v}kYgyc}9&_|Tx3t!r?xHXvf|5qDv5mcd*Ai387Opr1#?Jb4Bp5dDZF zv(fQJ5IBg;0rT1igaR?BC}^q822LPr36;1+L$z`psKmu^g%lcM)?noOcMCGg0K1srldoTm4#rvh=Dge(5|C9|dRp z5pK}z{XBsxAJWW=_oqDB5QmG-pDosg)gb7a5wOEm0ds`6u}}@wD%hksymYPP@E*M8 zZNIh}rh%D*IpV#4D+)6{G*6M@1tVpGe-$=?Z!hdAs?$QHflZ5Y=JMiV>aWat&O*+Z z`y4_J-}p-I8Z33Z^{Gv2N!1^^1%|I`^|1ioH>V3|6S!J}xC4>hVrr>GndfK!R$n9M zS?;#2hD+VNGwCL7)5!~;kV~KYt=}QF1po3SqG^J7_Ziw0Sn^$w3eB^}QdfucrZGJr*{X+XW>MWso#HOd1|V8jt;& zNy9^=@x@z28lIB!MLBtv`a9+xOP=-MHrxfEBWbGZ%em_SkGbU&CHEbTa$o(CzeZ+8 zy>FO`=4`O4fe`k^KRPa2}Sd(8H{{yX#;WNLg=TOhRspje;=#>zgDK7LQqhRECnO_xpD_)DHhD z@0G^x{Cvivo>^P>T@M_@SUto8i>*{4mZPrl&QYX72&Kw9OAk0uK(*-Roxw7+xF<1VC9GU7dfBU1g)CeRrw zkAQ=6sru0fSrA~oRgTE+%%uNcQ8Ye)fS^(|bR0L4A zpKkK#dwF->Janotj=@jPYRVr49%jGs})%~r-d%D4wIQuPxzqOtY{BGB>h zmRuyB>hNiScp8gOE#fJJPu~_#WAJINcp8OICyS>8@kuBE^|kmkMLdnbr-?up_%v2L z4a28e@f5(PA>wHWLczZK2<6L%p)L6Oel|7td#@9ZIFI_hi>$}1tjC4cW1IEZYCV3> zdc4GXyvTaIzrxxtkRxh80c#&5Dy+)~r$UQH^@2Z$dKY_P$vL+!+R&ep z(=~UH==Vo2(})zZ3NejOgRJ1M#_fXB*RO~dtsTC2zRVY7cOAhSwE~2&dEYUp!8Yc6 zpaQ{@0U@sK3SF7dk#Xjoi|V3op=%$bG}4GU=omy18XXfXl?y$?oVm@WE6(a# z2c^K4(<+Aiy)K%&EoSGpA!d(Neft>FnLDvku%%Q6hM(&CwD2;d-Y-MR|Qw2jT#&(8aYEX@&nNb35SP>?A*1Y{1s3> zISuDcBe{>*RJoF!tzTEr**}Gxo$a1z>+D&RWoK`HUc&Lo(&Em(>hMRY|9&5GYw`5G zK9JX-iz({jOOVxms5zRN86v7)AgZ3U$-H~1>|cY(%bh6----2LTwS5B-PC6XeM&xf z2!W3AKt?1FH8)MbI^lArka^D}3HqDQVg1u2+@((Emhwl6nJsrZeURO`Ms}E)&f7`2 zZACk0Npjyw^};d)TPdmf8(#qU1C~CX54OKhR-Y~+6^m7{8(-}gJZn?+-B|Sm`xp~r z;Bmh21;rTZ6l17k#!$zMVfz?DpkNFkW(+x|c^syBoRIT4%x*xzfBZ_) z$tyP_W0-t|#TfQdVWgnK2#|0D7z5Z1?^`QtZNIrB^;z_%3*>zE91xk8E|5*to6i9e zdb5LZb@QJ6yr25OzE|fc>!#zBRmOV^6a@GBWYqAE5-;Gg*LH-CT}>Cb?BVD~+uZhagO!)P3y7Adi;E? zdi;ZY+#i003#!1WiBUWfZ2{{Yu#_7_qb8Y72qO>J3{c;Bqw-7HkD{cg|K=v8sD~gW zwYDxUeuX^V(7P2vDQ5W44y2mReQ0tC_^@B(`3x`Q`5eG1yX$oEYjo;xJem^ysW&t< zbYO`~`{Ga`l+r7@;y^3n<61}Sqg1O&@E)C&PPJe;$7f(^X!gc} zf{jk7(rEI*;i)8_T}@`EAaU5x=kM;oa$-%tc#|oJ-t2icpSN)?!P4Alw_tvR!m7UR zZMS(o7wmw79Z>L(6?A01R>KtlM54LsL$Cogv+5&pynndey5G3#KAc@t=j*al#-{ae_hjQw9X1}*)u+I@^ci`g)i z#z5!+9}SS0+Q%3;Wv{L6lvyjPty_f4)d9(37a^qC9g^=#sAOh4Fp6rN%s&KR(I z%r%v~S=L0m4$y}9-Pr8X9P-;D{!LmG^QyroKfMnq3lAX#N zxh4ZTjnPC5nBj$VWinGv{kd-0N$|pwfM1z$m7l#(oqhJgXjwCI2{k7N7-ed7@RB`h zABR2COZVvOJNDKixPaK%quhY(d1%Fe8gN*Jpzv`Y3JNg(wrvBaP?%E37_TnVQ*Z=V z-E5mNKcv;S%RD6tM7E;2TNMa~lXV?e1OQk$3lVlQi?P1eU*_GZB>b4dBc zv&=u1h5D6vumk}MayARzAkn*XJtDgWv(ZWs7P;^`wLur+eoHBFAMhDD;LFPT(n%6! z{rkfua4J`dt$=E1}Jng{Wc^WaJcxh96gEJ1aJfN6lrndAd(AE%y?iftTVfndPt zZ@TNcnS)ovizkM|U8$c#hRchP8sQR%3c<&Z!$-W*8^HBHU*+q1`>#~QHy94m`rv8Z zb{{`R2|dx=ukc#U=xW#;$2;ZGH7f!L4)pVtNjNP$gabJCS1S=2`)g37ff6cq!8dT?jWqkY*E!lH_M8y#24iH+K z8(?jfl#C~Aci@HAL)0Ah1mF`m@=-8U1ZuDPiC*NdtEdtQGHxsdOf_YyyYmo!G0rHB zvuI)-`JNZmHRgbIYC6@?bgH9TXP2A=FZRrN_9aA~CdLBF#Nc%%m-)3W$FDD1s;saaVsc zvcuJ2w?KFC{piL0H0kO}ue&gnjCjc6J!gH6``D93!ejy^wHEa&EjhzVv*}z>Vi&0> z3(`^6grd23q1GtRR#$F>z{X@A3QX$W3Uy>>;3E7|tjHm$QOS=EO+$Q~@WNpokprRh zbiF>mGoN4RUp)fcLPrb}Vj>2U5LsUEpA|C!``SB+{wh$imF3?ZD$4U{h(edL;EYRp ze;=}J3iA?f<1c;zUyPwKP0&{qcm_Vwbv#p_hwvTKHp)i2;FBDUgkI4{5QS9z@N92k z4isO@lpAt1L1M@cA5eFP#hTK~CHOI+#K1E+jlo)B4ipvT7GhRE(gf43-nC9+JE2&h znt0WV!Pus|<_@H;0j!y-1}+q*RNYd|sJvdevo}v{4p2;w$5DJZ>XW}xbE}u?Y@i&X%l5va}gdhIQxs5m|+fyN? zLJGt7IWLUcF6)wYz%`SM6NuXemrJA@=@L4K<5BBkvJv1nPj&fI1DH5MsSc0U9>7O+ z6fd`tqEW|IkePsE9ii-Xc!eUsf$&vA$3SsRks(7fX8B0yO#oK<WxTw$&muFRr@r;eg_l)7BQDJ zMj{bAA(1>aZA-fs)nAbZwHZ`}SQmY$k9)J@Ts9)Z*znPY-a+t^3BG+F9e$(QXVvC| z2Up-B@u2y974EuL>6z+&QOf+r0z8o(RzQH7l%@kbLc@-p4+=1jSckzOU}3naseJH0 z_b!Z$11+6koDynch-MqH+BI6h-nn!w9P@=pT^Q7>WbVpelCSJ`tfCXrfZ%&=STY~y zP_DQOB}Ni{Q4Qm0w0c!)lS{tgO{IMM`-}HdnC_0I^gTSp7$}9tH+v9=0L8L*-kY~! zkd5)6*&krdI?;|>zKM2}uDua{g|7YL&rsI}7H4OG|4aL+7e2eU{nP^cORqbob*l3M zj;wv@Z@n(-Q!9V|KJryILgQ$ooPDkd#HQKCFg?Q>NvP2%c3x@74+A+xOwP$#JE#*7 zR49@hvU&^*qxKkDiYFVer&7u|^=c{mN0g)+QIVdkp0Y_ z2q7naE@qgzZqTN;MdT7AUux|yA^S_%{t{6y9HtnbH^ioMiIVzLS^K9Uoq|f?RYqfv z=i{~PE`qJ+7_*P8WE(uS>+lySflo=Mvf5Za9%jiU-juE-goE%nNNP&t&Kma_2T|#W79=P4|SF|kGca5epRbm#kiVJ zJt_bjjkAYN*ToGz3Q~D9#2gKM@(|gc9ic$W-d6=^;8st!CUeCWV2>e%Epy3dd(az< zTD=C@039-f$CiFLN2@{cW?JgtzUSPTxw%{r{?q}UxN{`T?dx0`4?{B#L$ex&uo{Li z4@0;VgDLJB846v6*gcBG`cmm(@ ze8d56&c`DS)ZHhYuZLg${f?(JGM6(Fz*Y`j8l zzIX!OFn66flJ2J+0_jcj*KM!DJO&F*yO;wEcmYqpI^+)sXvG$WQ!b|n>YmS0?Q1FE zAI|jxr%T3K{&?i$poo|gZ*yxZFhU6erBOBDzl`^ z%4sz8xOvvy8XWTCqz$pTs@p};mWxcwjTo2?kO%6^SXP8^y^E1L))2K)Kp<}j+utMU z29M*5sPmd8@R<Zzc;2EYVGf$T?PUL z{F5E#WAWv6wKfwn0i#db*fy59d}=+e0eT}OGs~|vGk1ZhXwoLknxEFGjKd;aj(#O; zkM_rK7XhC)#A6>)fRXV4rKi@_$b<5==AA#O zq-ILXHf7+m%US}!Q3U{=X#v3W;41(zPyk{LgIFs;9A$y{@0EK8@yo;4?0_#?2;Zmz z_`(uCtO-|>)Ow_|2+b>z)d-Nzxl=0vX#s!gVK%T*vsjG5O72ujCjUElBIj+%fuKww z2U=-MW49s$CdSM-kRa7UR7lUjF&2hpgb3gm=pY~+Ttt6naX^3&s8{?IU$$N{1p9vU z@2hn{-3O8CpQ~o3<*x!2i^+Jn@}|Q1$PPZt?;stfr}^0(+J1HB)nak7Mx zD~YU@Ge25ZOkqy`94Z1V zYNzEI=EXMlF^b~)r}{?~BblZpalMd)YOaK8lqCJQdFSmGV4=OoXHri7$6w^M&Vdkc z8C0SZJ3hd=i%+f&g1;VlJE1MEBLy%=kJERyp`a9b!Jn-}h*ld^h)NwvC=2iD^W_z3 zw2i(Oc*7RF^|#sJ4gaseTSEU7a*z+&_3k-WS$^R-a#P0p@5Q_Gw!oPWKT0Mc2q|Ps ze(#Y=&G4?hSse@%GBIX$)3JRRw}#aiGXlo}tiRYI$8cJ>Lm-O}*$m=&5Hg#;aKYL6 zq!0a0;3wZcfsa~*&yGmBYW)So@xg|_0CTqptIw-AllzxY#4D+HZG*KHBd zJ5%mhlFy6I&sd^5&lxUJRK2wBKwa=4I_?cg`QYpC?Ubj5AhHy9THv7>E;Gw4Q*l$V z-`9R-^?R6$3SdF#e?EAHs4PuhB@iwTRw*p{PYr{PS=F+)`wFP@uB|Qv5pwdu>7t5; z)iLfnh2yf9zHDo8{C;H0^Oj*ODIPBhCS^YIaHXg-{yu`$L11+tScjV*qh<`(3Rsb+ zIQ*C2z@t6Q=eo4q;rvOw{b2J2`eX!(q*Szuihk`}mletkND)kU+FfYE16oytT|$*_ z=!Ia?a8B(e756Ul0n&(?ghGbvt71D+V~MzTN3>7$uk!x+UOZ?!5Uv(BZw0r!c|y+- zgz?h7bgou6mpxPoxA9@RA%#uz+J`F3?6(xVUU4|k)VI{sgXo5|9z*<-`E*kgguqpC zcLfeH{$g^DJ>;UnbP196Wl_)pBj_Ww8KRX?oJ9_-i&K~5NvSAW50aN5zyLU3vb=I{ z;cd&t+n`Q8kx-qIL1tD0gi|iU_;EmNaPf`6=#nlQpJ_JhALK9%ZX2IzHm`r65`p9t1eh5ip?szJX)67lN3=s?QE|c&C zSQ*SOE@~*rUFl#PwcLp~>M4bz67;F0eINU00vZJ0*XFO8rZK&a7E{bVEk`H{ixGv5 z5}3%@ug#pWPT#tt(b!m6@Re7{!&oXL`jH!@tLH3x*ct(12vQgq+9W4zUx zhkHR~&fDScRT5iCP+ASUYoW5yOf3Tz-qncX=)mGz0qhp@*!wFr+w0C7)NxE!nepCe z>ep%T<4R6}A2_#twxFz!Z=kr5{QZm-j_Mx2L7hguOd0Vxuf|!l%PQJ{_jONW;a8mm z=Yl=~u`R3Fmi57ka*TohoCZl9babi1#z0Or54uS!k}HnH!bUu9Yc))3Xb)l!wx{QG zOAkbQ(?#~a-j(2?eCX@d>`a8l@zUQ3W*H1aHKz>?_Kh^#l@f^@RO4T#fxBPBr-stZ7#W5bZXDz>7fsW!_TpEYqF&0PH zT7%=CCd^46z&KOWbZ8#z-|p(* zLvLbFn$R>o-gYrwF%DMXgwntYKDK?4*73&4kVxWaw;|HZDB^8GrYB){d&68+;FE{I zLd-IJ!u;T);$DWhm!ZO50@ue2Vz4mz0l;Vponw?5%XpNTrt@3H)0tlOs~%?+$LzKF zWlT78O1J-S*Z#I|uc)B^F54(eMUJN@Uzfau-)8yD1vm?~07j$ors^o&3hXCGmF5q{ zTK-5j!>_sUdUE-ei2#gw%tw@HwXlQ>I2y?{slMqL#TjfBPyyY}{!k&1 zdg1pR@7OJRC8S|w;$xtU#W}&Cy&C>A|NQ1rFfU=YRXfrPmzk z(cTpQ`i}BwyTrd4M|-qI;@<_wIREvDG(F-`;m=#BU7Q`JfU zHxH16S{pzKm0m*h0!$x{rJ(a!H$GZR{LeH^D>xhs1L}dzcs|ime3iUUoE#? z_5l3_#9y01!~;Ug7=()LL13|gUkeJp-4e2VyOhIe#PY$g}QW{}6+{>&*ZqW4bhI9-YprvnH= zh4`(?;+t{e{_Yz50!ontfd6UyorGZ|a&!0^bxS&w@ic@fUB>=d!0h`_6%p+$hh4Ac zMx(JC1;GR=fmm!-#C-ErJXUc)KDhDEJM;Cp`2&On7cXbe5z>#Lg5M&a!fgs-M3zSr zY6i>sg@WQ~6wh%5wqt8Fzl`oM1%X1IY=Lz1w0|JDgRO2taNJmKNcQ(|d(*kF$Mu%7%aE+;2y93g#FfXel@CYPAK`CvrkqBKSOpB!hfdeah! zgis-n3v*5=BhkO8$8mq5X{nnP)W~olVQ+zIe@78?rwa-)|M^eMo5b1xgpmKm4=5OX z9Pg*uAm5a*9~W@Nnm|Eu-khgXsEEl+AXJ1q_dS3kln*}4(22+Oe zX0PFfBG~MW@=aOYBIYa5s8Rj80iC}5t(_45;YFiV=mp34=_qHJAIx!D`Ks_DD|5Vn zBqsxdWP+>Spuvlq*GzO_z@wZWz(4@LcvqAiMO=|qYsrv8_0B4bY?RhJ0BNR`u0L{U30Y2J`81!d~mqfuku^%q}Bx#41E8& zY@dE(wYYhZ@z%g+qLXpXre825lby-_Ddv%MCX;mPjStdvdka)7?nr9zQJhj7!P^dV zX&}|{NPxJ!j3fVYi9_PZ$ZJ%>Q;6d%1P?S{|MzZSu0yT*Ff(_VB7qat^h&&LtM#D6 z(P#_?D+u&~MGsQBv)$;#3CU*H-(ce9f}-@flng)SC6Me@OFzsdSo%|oap{N2X5Xb6ZH(VRZw~(XyOe>*Zy7QA*`yK0-m0P*#eOVZzW9BaKmq zKc3*yavQm}&f2><{wTRhhDjw!!EJxZ!${Ro0ePhI@KhU_s-os2;wjf}zOamKS0X!R z{;-Wslj!_qLPG8%X~W=c5S!mIiY2sTqMN6+K_u>-?S53vy&sDQ^O}!$=gp1_L~BDq z3NpaRc=6kNcz_tw`l@{1Z2Mddlx;b;>@~`4mZ@Hz1m5_?>pSyHX~@66hle~fXu+c%Zv!i2b#OD@|MVJ4Z~^g>8!Y4vh-Hh8B&qsO zHpxhAkKrKKzXuU=F##?Eg~eIm3~!t{6sb)ts36O|gfVj|svd{1a9Iq@{J@Z7CR3id zQdu*P7o$_xCPzmW7$H6(eh#mKo_~uwTSN1~`0s?=y$Tqs#|o?{7Y%{VL}&RugA($~ zQ@G*fy*{Q;yP^_XGLi`tN#gC6b4ss-C4Mu;9tCz2hTfUqhEcu4C9Q$@ZGxw zTJ(40po5~O@k3NTMC3zQK7?E@4R5T0l}%pu#L@gS9K!q`nM&M!ghVxGG3Tu`<#ZP1 zj80ctFH8R7!eUD;Hc;KtFR*#HC?(KwZa<=<8(b`5zE+i+8$ zCF~&!)$dw0qMWL5$X;;kRsCR6QpId0xxpQ^AckQjC2MjyiTAydlSx9@6OBpnr+2z=ljC1P_D*c9SD7$ zbpD{2uQ|8E$mfx?-T|<=SFwOyMr;1K2V6!U(A1Vyn6%UY{J4@M;m4gElLK6za}AA6 zD0iTEJL@|61`O%+E`CGw@unSaQ2%Q;hKR9z5<~Mpep0&TOcUe3V94sL0hXR^088!w z%XOCoq>Uir8hiIYEZF)}WAxH-j_qsPz)0l(Zciz73x;4^(atm@-8`xlUb2hGXLPJu(qL_b$BD z8D4uLh1Z6t=kHzu06}=|iTU80;)SMejmR2~%056iU6T+_hgL-4>E?(Zf#^GmY7WT0 z6a-U-o#Pl?_Aq5Rlz;ychGd$+AOzQZ>k?JgKHB=CeW>9LiPvfzZ*NdM3JyHv62A6QeE+FXgbeSli-7=~0iq4> zyCT&}DP~b&utlim_d=`u4zd>@=>=>^ zim=|*-(ydoOW$w9CPfw3qwx^A*1y7g@?uf|G^PBpE!VVY%xSb@&GE|Dh32>fD~7!O z&H&(9QYgSZn6Zn05eQk+Y-6oLsV_C%;zQ(G#Dw zcQpK3*^X9YN0mu{J9^fH;*P5Ev+ILK%%i7vRI&LhAG~}67^!k2%-a`$^?Dl?YD_15 zWmUui)Jf9;Rd+B|cQP#kYLPL3Nlp|+CxTB!6)hI?aGvpp@4k#54n<}PJsKytJ?~tU zJ#Q}L6%c(Ndl_uhqc5HBN0%PUl8W-@pSFsM&Xr<~BY>2c#?rYzr)W zz^-5yHzeTA1Cn## z$Co?;eg+EceHWcfWR&}6%T7VNgQ484;sRkufv_r2I^QRi=u+ZUp}dG=b+Ntc|&F-q3jaxg7DA3=%c z5h)!t!{`Vpa}KCM0O|PSaT_EKc!{f2Z8MtK;<*kX=T;og=1nD@*cyozDa4XPz!gl* zps-ROmLaIBh3DT9OzS{_qKyZm!54natA6b;_##S$jCt!7C}RTdU)=ln5K*MSqfIiG z1}BXGbY6`ZN3)_8x{wke4mtI-&vuukk+0r<<^H$-{k^qc%paA~i66iDbtg9&O7u7U zRaAgr&(+>o#N0g7xo{7mMf7j4pptSa7Y+>6Bc*yD1RFE~=o z@?Idx{_Z-HcJCCKnwL+Z8NZTe{7RgcjPd(7BgQ}DnH_{z5Yw62XR( z)?h2xrIEur6#NmiggEy!K#n&b`2(_5kjc|_3P+H@6Y{Kv4 zZ8xE8qpX2g27Y_I^V{SgDhjvV2+XWFm@tD@ZFnK8Ha@MzAGbfVQ6nxwJ)%f3=-DCD za6O|mfA{TN8cWD78}e6EAJ1EY^$V8OAyo552m);DH)8Fu$B}A>=YzrLq{{*j$oaYM z(ug`U=+5B9_TnYT&Ne#PS-JBo zy7|ocnq#a6;I-PhZ`h>X*zUXxV~hI7xAGjg(W3r1O~@NImZp9O{p;X%^Vm-m{U4#| zKN6sz+^}uRk?yzH9f%U}!4ptKGB}L6{r{xQ6nuT@W!pc#(H?3<`S; znEKJhh$#T4nEyHbd$>JA-ECWq#*LEa`KW)JSIYj~dia;?-};TvKeX*Q`gfOWFa4`7 z(ZAI#U!s3xOH%zi(pAvELVJEMgwino{;2Hb<6%cHF_M5-mcSVomnD0jw-)vJR57Mt z9BK{}j_O0&UV1%pLvgQPya;;@;GJKR|CSuj(YPy9ay(1o=Yztld5iVc7R#(}z?u8U zA~e^fn-$Aze|t$tWq3iQfpKx*;&Q6}t>(N(k%w`i6QIx~%&-+4-?kcr(CE@jqZSI+TQ$ar z!<;t7x$wgt*GLzkzk~S3hc7YT$U>wd`*piq$FHy7gDi-*mfH^jS1u?+wge&>;8ooZ z6R(PvsATy(w}acB%av6rttOgN_X%8!%r694Q5==24biqiwvuBYKS~Lu@2Y>Z@-_t%4gK%pRN=3cZ|XG`&XEqi}e2HkoaVGFhiuIa%jUP{9Iho)i^H;|l$ z_Ub6H?xPI4sw$-JWow3SBlK<7qrNTH)xIJ;FaH;o0#;pO_uDF*}HxcTZ%;2}Kvk4qg|fa;=X2 z6mw~Tq|N51pFq(QxG3Z3;Ro#osvDt1;g!-(v_{Q$mLe-F=wYe;VUU;(m?0}*hP02f zqRXLk$=Z_HieEtQ#eNCh8Lm~6*IB_Os?a5P=J_R!+0sIOpRs1R+eBo(y zoIAt-%fmFvhdA-T=q`ooES(w4-zmz&9hTgp`AuhwBRPP@FE|bx75n5NUTfGyI_G(C zmuli%K4HcZUb9)3L2BtJbc^2m{5$oG{hNO`>_!I~rp%sie(CuaRhln0kSJ8&&Y*RE zKkvVy>zE@F!>#5GbGaY9xIna7a8Ea{In{ycc27>voydhGFfrBJ7Q%{7nGxcHBa3dC zkC`LRpq8WNqEpE;C}u7=Rbj=pgRwV$)S||A;aXrBgzE#tC9Q#{Ly@s%SO%-|`AiYZ z*xP-lt>&qx6W)-pJIopU3Tjr59gS0F=krdO@LVmVs4PqaVyPQbxS#5;H-Ho^s* zu%G3Jv{qX1I@FN-ZH?&LH)%+29A9!s`k=@}SQ~ZO`MnIzu;RgawY2_6(xXptSA^&E zHE~M*>LSaqgpJBPI7y+)#9ib01~TJ@#d4`)au>WZx{g`sOlIb#M4j z5CME+oO5yIrRMvhp)6<=_A6hbW+YN_eVqkhU1eWio6Qp(fFA}W&LUzg*Z``6EWCdR zDNc@-b#*NBxC>5)zQfc&#QeV3ZW-VA{BGg-RaYqDV}EZHwc(Av+=&jN^4QTX&CaZN zUHul6zFl*Q@2%#XyX{?`3;?$2IN=Jqd;nx6pvx<`%Wy<{IZs)G;+PU5mf(DBvN1eb z^31PEbi{E&Y*=MSN6S9=4TvYL4j-y!d{6=lZ|&Rzpdx* zef*)naiy?GlkhoG_f}nt4B@VIYHAslVRuD8`*~kp&)Au&S6Ziic!L(<2f#?k$cUlMA3S&lQ!CN**#Q1%a;(h7ak zB}u~0Ig{j5TEWHCF-rvHfxe#nxLcSXo=5}LYQA?O4pfWY^%8XQ{6cWf7yOOfI{8U+RnOH0R5&j?mo$;!=B zVB3Cm3>nOO*mW6x6(7z&EsDeCrmW)hdgx0iWIla3eQ9@kRy_G-`0`%s%TAB2&EDJX zocXS&K}b?Wfy3YDq2Z?ntj@WIv>`CFq@QZiBg( zL4E#29-5Ycg+p`O&jrRNR}wDqE}J9lyFc zp51ww0EGg!THqajCCiD47xTqYG@Ltp1OogjLiqG40o)yk%62 zNQ5TLO-LWfu}u;=nPpUuC;$b`9mnVM*-aiz-OTb;TRMMVE!_+)oi9>oBk9Q}1#%$Z z6jA;Pcx~|5(db|NP0OM{BReOg+M6-H1k&V`n*+6dQUSh=ZjCT5fklkZywz?Xt%K4p zSN!+bJ}0pc9NaWh;NYB!{~p`_I%^*-g`lN>xh1w6o)BGp2l+WO1+3=1J1zex~|F9jhLo)s{!ZV*tOf?)A%lUscZ(02Q%F8Z11#Avq-4Of4z zS*+!nnRwHy4tPc9Bb}U&P@eYqGwWSt+L38;OVJ0j?@%s{B_y30@>jEe3`wcp_-w#k z4cr8#3$AnYg?=qHy~ow=&iz=X4ZhIYbac?;)3?ZT(koWj&q>25WY5KI3u>mn6Pm%X z;X3;-@N1$<5Fyl3{$(iX(KB$Ij)iUH>)kX?>w)#6sPxB2;dr~~Rc0-XUM5-B%)t|~ zFY=8LIQ5bfV0#+A6y*;tOP4(}#4>cQ;hi1>mroa#4x++yEqjsO@l&xT9hVyhiLQ40 zIA+75K`L}56oS=E8;GkJ{FvuLA~uD~k66gAo{b9`tWPCk0F+wKNdI8zJFH3RJFHP3 zdVmfaXA)*xPym9IV>t!YhKL%16`E}bmTNQw%`A_z4)N#?ONVGNzcpRz5Z|1RF0~0Q zc_2n-!|BMoYWU$%PnJ|N9Q`YyS_`n9i|zQw#H{+gi$=WJ><^YyyEQ2Fq|2^$12YEo z_m?53>dmwDH$M?yTw{H~+IRmFJL~-k6iV>wsTApu9HlbNdxrKNv$E01{%K zf$hiDUQb`^;_FQTtL99j?<1^2NMjWsjs1G1Ajj*VKp0sI0GvC*35qOxKa@S4%bEf1 z9AC~7mgger&5E4@VWx9`n|DDmgJ?Qzj- zXiLb-e&BJWMcrxd*vEeDdAs+vUt1Qw8-8lvTW0`RAApqn*WbqPA^-Ef zd~n1)JJAjglk!|VZ4f|unu2+@2>v>>uv|u-Gud% z|2MI2{gtvu!>rYi@7P`T*FPv2(sxOunC~w%F=LVYpvVjYv_IB@br`&PuM7Uxs@~$_ ztpmAT*Z@nyg%8@fU9{Bv=3UQz<;=nB_M1Zp7I|xz^nZL1o!nlw)DO9#nK1hgaBOHM z598%6t}6Yll6wdp!tYM?gy+ zgFsMB2}qo(2a==dQAGf9eC(5&2CdEbdch4itU!(zbSGvxH-`{M}PDeF;35Cp_k@RJZ zzl`yhC=J~WUoN%2j8)s(yg3E(<30EShc6NW$!DMBVo6k)XAP>`zbam*>_}mlm7P^| z0vXJu4ZRhb?Bu(-3JAinLL>J}s3bYmU~}w1fC&6~(5i*79;j!!>mmSInno0Ku7LQ> zVPv#UTMoSURAabBHh@x(VyGq}UM6gW+p1!4TNM|kfzR+|fI!5+0n#i|FXu$?Q*SiZ zSy-X~Zn1{^oDlb>6vf5NlWrGswKU&C?^-3MipuH%ado6SECER@}mgophYjGYzEO}2>nN{w?Pk;(S&_k#Ba z)+wZRgHCOVe|kN1bD@m?1Et`CM#_R?qHUb@AY`>vXmrV|nCGn&dvdO*O%zVM)gl(w zZP!jviV>@2ahTsb>B8nw_97vU&Mx0a;mr@$Cv)+W5QY0~ouAh6=AQ7ZRNr_imReWG z0bAFE0OTzvQ^W-<9lwAV;9iU$lss5|a{<;e+vtS!H9%&jA3l`L^jyGBgYYeyT#{qy z+pcwxB|nd-&$rB~lxQX#%H5a4-I|s0RF#F?6Ymko9qiWZt$M6hqXn&ctX89{)w8ix z3tio_;TD7o*i0Z(TQL>*42~i2YB&?w4GCQvk|I}LNoCAcA6*6?UB9f#S=Dl^YI#BG zJ(zk=L23`Ct|&-df~gM`q%OnMl~vq-qw}HJxUDf=tb@}}oq0?oSp`pXPH#Ltd00*- zK)cqra8E^d*8O5O@Xsnit>zCVYZw%;xX@aw(3z9Du~hF|k*Zyb%X@2oC%{J2*fwf% zN9jD33UjE9g`}(R5~9vbdxutFhaNBJ=2A?B`fMk*>hH44NqX^uSl|VrL^%VNi6_0z zxj%$Bh4~{~XJ^>G-NNPr0jG=yJZluL&J;)OY5EH9iwfbCF5w>ZYN3{e9P2P|NsiSl zYRp!<2%C|DGjRUyZJNxH=ivO^FL7E(Y1=63w?N24|KepTmuv|!39C;@Cg`XX;|NBW zA4S%bs&^fUr_li;VRgw`KA4*bK?+njyUX68nGz9`r1pM{S*CqK$J98{MTsjQk?7(` znzwA<$cEu$Ck!#vsGDam7ehRVXyw%9dkXe?%ljWJsq2JKE){wQ_mxdu-{O=wo1oIX z@w`IQcoYoj(qgC$Ox(7D6<4`~#E>}6!PnDQI=TmtW9_4N?#a{rX*#0OJo9iefyK=x zd?K~Iggb3n{}BrkgmtMM))onCj}6vNhP8tk6Z#)@!3mYLG^uEJ@-YpY1)-e(kWw?G z>}`-sERt6%3B^Y7#gXQ@dz@ZBMe%pw=onsPUh+y8#I{(mMu{4mQ}4Mz7zdh>^SII2 zq$A3gfiLRfzT`k6sgW2UeW)$W;qW`qkeVtuRaW9WH^2=}Uk!)l^LFmQPG6gE2U~7o zRJF;Bdgr~0Ve|bXnSq*f4l5ODt?YU7;jTiJ5_v)swElG~gufv#ewb~Mv?QR6IDYhXC6xi>j467Xj4(VQ%*kwUjd zazls>aC}_M36qD~S@JoxV^I6()zi3!2wqJ=4A4z=Ot4B;C(#o=B2(s*RlrvG7D6Lc z(*&_R#{jerw(ayfz)c2k;?p5g67Jw_ho!I&(45y$O=!W5m$mq7oqxSeF!O)#wh)!* z5XvD27{pfyF?ZBB+I@g4Mg)h4`?MN*1Gq=QTU?Nn559W?npZ-I#(F5wb`S{EF>}eW z%54E^ZAvF%x#OU7K+#v!@eT1-W+SZt%NT|^wnn-{BiU^(%T3wvo_!eXa0F0hkI|9Z zO!dzXgQ!!--?%g1Xl#S(8Y*5)qc&sDKeQ+xp~^H3benG+S_GHE5|FiR5^_lH6K;hK zYZo6f-?|;^n+uA$cm3aX|R_7 zfRP0NtQv0v;HLj50PY@N0Ko6+%K^|^U#U3~j^CBfn@=pohC)q@ePk+`;C1%)4ixR- zHWl0l1d2Q){&FcS(zqY4)Hs|QLXF#WEUIxZdG={rsl`6~hU)!>VigzvVaBz&u1D}ryz|5xzs#oqh7jA-Ku zS`8O|t`#iKSma44LibMS{V{AB7Zwuu@McxYN;tB>_}gq-v0F0bSM2?VcP!L$Ey25C zM@e||OGJ@#3gD%ecoFakC%jm&zq9Uc7g?Gt@PD#oF9HWsfsptDV&r3I%aITCcg7CX z)SV#Wb*XsOeCl=iSVyio){(1EbL1|c=E(i%2uE&gf+H6+SlTh6*MXYm<<19$+8ZCl zCG~Vq?I0_?b(obN9j0pAF-Oy)9`(9WATr{%3|IxGD^#}!;SEwiXAQQbR9Lqxtbz6cfPZ<9c?|fpU$q+yxE2XouNsl{;IN>ssIFB2>rO zY{aGSu}V*LD-;m=q}gb=y8v@C;|rJVi_S_5rJtq+O8?}teP*{dZG+tBT{hUIAb=x~s9msza}^>HsSXTUOQ{qUvZWr~`~p>8`nGky!+(N%*)w0SR3j zz#?TcMahrA2$jBGnsH?6a;)mIg4BC3wY4C11*RqoQXj(9j)K&cn7XL40L{_>bd3YO zGW8-=wx`lE3(f11yfj{DG14LH7<;>qW4oON&^(2y-Ibbk7kjN+{|G>=ie^cZuDV_M1@R zXjt-E$s54n2uvaK^@H6SS|CW<9e1O{F81QS`)lC&lraPu?C7F)FMeAA(vqj*`u5mQ z#Vx2Ubt-P}=V6ZeSSw}ty66UhTG-REpAU(cq1{dtv#EY6l)he5F=(aI+H4+uu_OMQ zD3?2r_mD@zz_!xB4puu&6f7KVKQVZUv0(#sBsQaj&5egJuE_?udT~k5l>Nc?Z$?@8 zE|2G42c8FwEPwj2Y5I#^Utmy#Frb(iZ-}=m z2vS9cFgW;w!NDP5zY9ROARmD$Hk83_uTQTl4iNFcxXKb?F-rBPgeChQAC{a*V?<9d zZnrb!(Hox^@+zDlA6+l{eYrE>(fb$Lr_gVpM3dw?Ve^S1xe|T$ABAG$Y-aj9AfZOF zz>s-+${IZf6_-5^C}q}DpehVxshhVPP}mPN4uqk|H*ChMk*g#v(fl1wt|WGG2X8zs`%~uC8@#( zr5D^_sXrSs&6yOIxhA(tfnXODkRqfl>`>4YssJ+ge-er)a%A z>uSY2a>@SYea_7D%(MG!K>PXr^~>u8`^@dknKNh3%$zxMrf(~52Cyjyf?J03pdstk zN0IX^5^J1pb#5hVU4DInzRWy0Tc*Ojn#(5OV|H51;d}DI)Bk?`8 z7~i1b^slaCAY@U-!LCi4+Ik+!dp*51`^j(eKUmYI*#t zx2!>mSYJnkBW@7f4@-Dx7TV%H%N%!uHKH;0wYPcP4R*Nh1}_&~5RJHJFp-GjI1#9e zC{fg-F8aejIuv2IF-F8NbpM0z5tsu1gPq@E|AX1ZAZ3qfyeB)>tvIGvjNASpj`!jq zD+Cfl`y)K+b{~I)+3Vc(jOF?x3{I%<@ki*_Uus`C@+G4HP$h=g0e6SBn>{sa6 zE1aC$kd||qvjBT#^%K?4^QZw!46m=D4j$*P>@2(-xoN2N&X##^ zW(vox44ggNSvfOBv<1;(z$#iL$i-2|H6<2DL-zO9^HhKLz2xohJ?-a2Q9l1iboj1c_j%Xb$8rvD=qO&l9x+#6zgBm6*RNmvPjT10b@ib1 ziWPBY{THq-Sik{h%>9u#Nm|mk> zb$Wf6EJ?4!b`{a9`h=K$-Wo8eM=@ieG zI~8ogFnKvJ=hSYBf{|G2OlhZW)M#XR<7|DJ+_+G*Lx^Alc1BoF%Hw6X5G^j>n=7(y z6xp)3p`9AJkj*~x77}7+7CtWhD!q~_O`e0fSiS=^bcLOB>ES$DFC$mFW1Nwy62j5)dL^Wo%7Z!1q<&>&!R+dbtF05lI7gh@J6{B{%|jv_FkM&FzpSwe`<5~ zPqRwz_u8B#EuV&}&7O~+?00t-?4JIc`h!E%AMmgLn|oM)AHA@B`k88g?(=77fKmtc zG_ws*1kBk;{3}mvXfalDzCl(;e#T_Loo@s%tWu2RIQPNtgj&1Uw+|7nQo+ zW%W_XSrO#D8GcFBXu+!n2U9y+X*Mr%Ck6SpWoXD12AqB#w37l{l7l zR2g@vDX*zT-4`aLiERf-Pv@p>l+KRyv~c%FqFQ=l-r~(@zIOG+JEZ$qwHgrBHimB= zFqpw93airi#EtRiK8=&L)O~}49-n^FBeA|S^@;xc>?w&%tSXH=ior6}dz9B)GiL99C42*r z4M~J6_3&u%nxwcsdT=+!M76-~mlXPN{#^K;b*Ue|e?7b6v*GJ2A4tEpszu3%jz4(x zYt90v^97^y;^@(D2==?(@KLLgK&Za~hbH^K^Dvjw(Yg-@tuc7A~iC`@d^qF)jC4!%6(&;PxJjW(40tt5cvB_{(-_CT~ zv=&A;vv-9vc-U!jF?N z1&O8HEP`VPR7)F4fcv3w<6L@wl|0%u+IOHXwF;9GuH^eUKB~i#SGPrmW`TaQk)k7& z1c18V9^Ma6v@qWbsIJT&3keefXwo|xE)x8o8Ota-~9j&{SvMhfyK|JM)8c*I$s_Z zJTH=?bVjn9j=oK0){z%*A?>Yrt z-eJ*e>ZD5NF)E#r(-@8AT78+z5l*p^od5JW?vRbyZ+tYUJE3kaec@4>k3nv;h69i{RQ5 zXsb)cKKa@=zq}*Q%iYqP?0Y)td!AjWmb|Z--=jx^^0n7;T@kLU-l?lz)>ZFabhunh zeEH4?gN6Q4Jn2V%Sdd=oJVs70JnC9`)U^c{sh0%*dN$pjPbnrM`ZWpRA6_Hm*?i)s z9`nY$Jg#r)sXB`~Tb|Un+Q}Iv-6z`5!wId9@DX@4lcbK-2s%z1GT;8{XswX(=lW_gSITspou!4(0V;$|ArS5Q7`{A*x%dE z7t$j3uK}Cl9)6#e8Bq_j45hzoW7=6hs_fSX1I4=L-NDoJfp~lS(Vck>;#2?H<);&5 z0HSb6Y~_4d+%li}ZMC-4ll9dRy>A?j0h}qX&+UzmgY$UE^558`7R;wS=`5I6j4?>Pw|tC2f3!}H@&Q<)S6m4IIb+0A!ib%p! ztcQ;X(0UjR@)Z!pQb|l4a=~>S1<8lU!JJ~L%^{7WGeb0%@?z(Qj?KmOOpQFwF8eg^ zVQs*z_ms!8nT;8_7;dmfZgm#Jej?3(J>2zn%}BJ{{87KFc^V0i66Oyc-kFCypw;_V zaWgeYHt7TWXuV;$k4Z1%SJ9yq5@qec+<^OXJyPs{ZN+|-dU|*ndcZtDK=_B9LPp-JY7z zop%uxa>rFy5bS>vE>&0mQVhX~zYDJk&YxC3B2^VnKN*}a8u%Y9-uCNHzlh!WF+IhSuPBJI-W}vZI}I*`s=Qg=4pq2;xpPTpaDg|=Neaqp zL+(($>Guf`Es|{Bl<(-kZ#Zv|-wj=e%$;NgzO24sB=-cidv=*<0jV*u_Y*lUB4wh? zfk^v4IBsT##UdYmj8rYn2l?6~Pv0RQ9D?E;i`#B0j4O(YM>yxm)3M+QFP=Tfl3YY> zJq<6}b`wW<8*xRbkgSvcGpLRbFZ7|u9m7h|$e;bb{jzE9p*m`UIQx5q$G zd_Ij&krQLJznpUc)!ZUEPP?Vc>h<(1Bn33tAKaf-&V#ERl!92M5O)FViPHrto5?Ok zl*`oQ4slh;cKe}c^DSw<$ndC4n;e9PZmvIN}u+krx|IG zAL&t-wo!++N78{5r9|i~iZaW4uQDhvcy_?eA(y2fD_Ho!q7F|_&1w}rb*sGp(g7Uc zu$va4?Fw7O7~$>>9*MbGI_)I?-v9n;KCjB+s1AuVwENrwLNV7+`kyFug6{%>} z65r&RrJ0PbV#D40_n>i$WHbksCB1r{d?CRilxej8Pk@BMaz^`)hVrddj69WpA%ybb z?t2aHNQF-f0k9E?eiyk07rCfnjkv-T7-9f(YYS?cH=2YMd~bKHrypC?nHnian^Da8 zVS3blE!~K@qAs7$LYeKz5F+K8tdz#H2B8&X;yYQkVkTN&R^gD(n=%-zpo2&Ff|cZf zAfi|VqT+JENwwlWd>iM2}R%dwb^Vjr(p8t%T?V1`9^ z31FwCVF;W$1#`Md^Q!dypn6n8iw5pB=P}JYjlvej1u^Ug<`m)BrsKHZTBW5Lu@($q zubVSSsU(kufd9wGEZ~Rx3V7f3f7jb&Hm7?f8{qQ*_1)=wH@lB3z*5k*a&jEY$bLj# zB_oyT-zr3QJz*H?Tmr+yaCvq-GGWHGr{{P*+U9I<5-gaI$_p|P*eU}H5ZERI?T)zY zkvh7VN8>B&l*92w!x0;s4J9_P^Re8M5Y;9^|5eASu5@A-c%2E4-1djB@iwl_ev7`i zUglGH1cS99_1Z`oz@Np&lGu73v;nh7Q(w6pPqwTYQ0zl<(k*Y-)95I@S4-^YI)FjH zp^;3{kDkW}NGc^9Dk-Z^P-&G*rIjv~Rv4~u1=b)`uOyV}XTo;vC#3u8*kk=ZogNOz zyTYE631y?%XgSYUG+6F)Pm;>2?~0x#39}YXzY^ro&V+>(*vJoGaeC9p(Yjpnz!m zw^Lu;&Hk-eHK1)*3iS*<)rMEkP^@YpKY|IApY*K#&glWUY>-Zmq@ff$oJ9L(^o|zt z+o7yEHd@Ohzj)N8z*au$2dzu1eABO`zCB-iNYf5YC7KU+ z|B@JumOG6`@*0PMVkppIe{qm(WWFjHBE2OhLdV*}PA3_?H)rpu{oCt1rF)_49|b%? znSAYmC+=V!D3n*Z3HI}+c?vO^8)^?FpS1)}G0BKV3llUGHuIvdUXz5k%} z6oL^zPqGjzb=2iaiBFax)Hl=>mejaDs0?7s++s=fiA)}~-9!ltt*`G1I*mi3 zL-cKAbkaDr4=?^2#D*GRzV~hX_haNN(=um2o<=m zP{M2;;TFi({@{dSCCu-Fd)$EDT~39|f+ZWUE?%IzS*6zRd#bvj)?JHzwSc{oT2QtA zu07Di9HSNZ&Yl!7v#?Cn$i0+`gWmnRT87@PxNWC2@T=5ge?5!DN79@3-k0T$V2e?x zpP}^OpU^lkv;Br#+Ex@+_r}LE3!Wu%VmHO9I+HBPNav(4?BNI1K7(PCgh}LU@1KFA zgY2s`6xP?bLKiGn?_a|@qpivnbL*XOW zIAc_dQ$T9JR*7GGuQz!M)hhdya7)c`>SL7?7nv2aUwgyNo;yk~=Tk2W=Db)AMS2!2 z`+?~O9@Fx(DIqoirpBdcb-wnsDKt2`@h$+mXtT+j(=TyF5qsFj46IG!ir;+lN>|{v z%Z@{B_NR1vB1!(3DFMT(X)Q6RM1sb;EQ2Q6AMMm?P=GrB#yc%UX2XJya$}sdi$$7{ zBA*5^!OWLJf_Cy$qmTs>SNs~`?i+*d1R-6$A;q4a;EEBz*=3A$RL>MNtp{tPD{1T` zgSnOS*B#Dr`Pw;RT*N8%c85Q}edUae&M$a;O;R``4-k4}P8K{>r+=K!yClN;o+^Iv z6V^sy0RznhQ2ML{Ube#}uzhH=tAn82J+*&%iFFW^`3EbtUfBLu?gc#bmdym@YuX-4 zQlX!IL_m+QpFNR2#)Iu*Ewn)Esa>kWKVHDk(hgW701k{#`$!!aOV*RcQ4gOI+jky7 zF6O##`Y(ua%XW$lm&MjTrCz#U)1W#@wOyKWF+h_HMoWmqhvOLR^ci zl;_yXkK2*&GO zgP!$&sr|T;)XrYmeI7?fa5wnuy1%tOuiKp@rD@5RE%VM7s(BBUYzF+;=Yv1ifp77S zM&I9;(r?jtGsoZK$p2nB0_jyl$OjqTEW;h;Y>_S3%mo}xGPM0AXMMQ^7>k}D4=DVw zV4nnpVNGua*8gB96{?O5s|A=GB96z&Sb?-L^Z)qsaH+E*Bpn? z?^x0bvr+G0&l|IiPM2%mbwo4HE!N`fX@4K}(}Mn%J$Kv#Zr`BW_*G8%QpY7H(Cq%K z@!v2Adfz_%@6J8J8+O}qj17Bylt73>&fDqsVu`*x^}aBSw7Zw^(5nLw9%ZuKVl!46VO^=Fg^|8fAF( zQ^l;ZfGBE~t#DW+5#XNg4B!q^jgg$HLh>G0Oimt%VqM#^`VP5l!g-R|njlMVcJ9=I zk|2W1DP$gkg7!&&<(b`qs8S`kxP(rqi9Y=3f2j|FyO&5M^qZ|>ZT?ZUkxxxX&zSco zEYd3n%(p+R<~90=0dtG^rX@N?9;->zd-U;ve$1@dS*Ux+6}zzEaJ3<6%yJU+qiO5MJ zW{+WI!@2g{X|6sE6-<0yRq)*128l(nO1tW4O;?9X+oc2sPfB3~{{NY6GETV@3R0FL zg)KTK*l$kt*7-N5&hzh}SsZQK9|JIp6lx_Y~WykUhX3jxV&CdEgI@ z0u1{ov2%E*r_g3*;XYWMB1qQ)Y`qG!(-Hv+JgcqGutBv zWmLDmz>3e_`i5B$vwD+Mcfdsi_U9g>7Rs{E8>SP;*Z%bgvAx|=gN5af4c-Z~2>_@3 z7dAhtOJ=@Rh+Un+j?PVcbY%>sU-!CMY#c%?)ax&WLqQK|cfS<*zs|9;~t+&KB>SY;1*{12T`vJ&@B#55fnE1isr z@0zg&{h`m6Asw^%{xq96j+GWH-SrWfOMKS5pHcU-Z-n!?-u>)%KUc|5kZ>d2)sgyx zVaL-73j5AP$J+YmYpft`&?15;TzsoEyeM#f4r(9+lc#uBFx> z=5{T{Gb+N}(|s9zUm1%6^0jc>vR4_yYhqIceNQjqVt?8db22`Z__t3L!#3ON0pEE~ z6>+6oL)QjGef~<`__z7FNJW*K{gs9z8w+HHV*1OU=a~W`6*7WED=j9jH|fB4=P?0- zSR+S8oy>?|(Gkab4whEXY_XIQ?I))*=(@42$U!1aX8pQ6hc(3nMk+VT;s6_K)7N_X zDGR691)aU~etMNO0Km&Q!+B^5E7I^phAe8NYQ-0(1tU4q5tU+YzJyjaJU2Slfff&c zHFfrIZM45von-OIReL|=!$9GKFNu#OFIL_?mG*Tb3L?8x@-R>L4`& z&X#n9aTww>YJ_T(NVr?FJxzfI4`&x~_flw&lsO~^96=}Bu~{BNF+B@Vy81u#_+9S= zGGfCIlzU{v)+p!G+_effmWj?76bRB=fewObI`O_4@L~!D;U5Ne<{g~c<-WQ>!%3io zTI|WwF|31)Hl5r^1H*9rLXS0bDjtpp>S*hfX;lX_Y zXbiR&_|6ouwCYQdzB!>rh^kgHs~~1fALskL=GLq-Ig4y^u5+YlMDAdh4M^8ZpS9~E zJMtdPtZoN7t$xLd`k6n{iW|DK=&kpH~!8tTev@)K|X8&68GTN3%H}LeXJ!~1X8_X}n!gAd(nTW8x?j{m_So1wzPU9#PWwD8ucjc<7m#jGC z1%gl%t}0yhInU^(JLeCnR6$ktJ1_G7L$f#sf6V-g$(nZERww~2 z#-_iR)Ow__`ZMCqkX}bhnGxBC#F908f0T4dlS zAwbRp$aBgt@YH439=2!E9+2J^X63^Q>gr>V8=o{? zAEfJ*5NrQQEL`|*445oagD2+{!vzeN{ZRU7fL%^t>x&dmh_}azx=Fd19T(KvkBO1m zf5})@IEAHpiDOS4E2m4zY`LlV+8ae&dRuMkX#2>6#5G~>;tj_c>GML$wpNS=Asax8TGs1r^=JX)^YH}A#u_)PvWiIzC zs>B%9xre0CF+1ogj53{2j8dM9;Fa*g-oJDo?)`TLuh4{G*+D`G{?5?1ajLZ_ zVlP^s&$~$qH-NBP*TZ4oOY@sE^VoQQv($_vWbeEv!!Q!iO`O#HMvMPMP!YZdrU^Z2 z&+6g<>o@z?pECV6QakG06UdFE{K8qwl6CS$3`pM!Cf=N<`H-<GazT3PPL; z^R(>oh!At#u~3#wh;*hRTdrE5RxfIC-JIS{r_5Ch>fTF85Af-7qg*{y zyr-s4+(VrA)9Oo=L@V6=ZI>{V^>PY4!~M}L$xvUn8fbN9>F zjvT!sKVyx-c1tMo$V2Fi+$p(zEfm~RlipUN(!S4W6J;gym=0SXl61&^HP2^C4fbUs zu9WX?;>R8{yGnCN!Tc$}hG-dXZW4((oU0CqkMy>R>jehp8u2aCR^q3}{E7Ja;3-de z_)qDnP5f%7#Nx{n2>~DfLdcHVJms|rAAfWf_7rq^_;?!QR_BUSq3jQ+?s8&+g0#a0 zL;o2=RC@4)%wPz}Kh-k#ei%BL04>@l76BYv1W@_SD9SpoDC?In(xm0ZMTYKylCEFG z(|vf{kNrLQc&>=MQ zI4}K0x*Rn>7vPNar7t7i7Rb}lzM8(o# zpxgzBwUv9bmbOHH9x&Y<6)6ItPic|BoUI;OYG2S!Tyun7u`ex?#|Wms^buYjQ-&Kv zL)Q*q`ByJ;WLs!KQ4)4Qhh5gL5yov>Cof^zW&ep@nq$afl(TC?WHv=hZ3Y9dI_qZ3 z_c}5yyq=)wSY1YL{<#|VK1%CQ)JtC9%oFhK(knK{7oD$TE=+ye_71R?KhF5pjKf?Oev*SHV zTh{Gpi|Qo1u`yy75O0y$G#>cVZ%t#}K>-chUmYYw#}C*+bHYfCauWVIO>2f0zf5ml z(v6=tf#Vf2mifa6tBp)oc?%DZ}C4-Slsnj?hP!@kyZ8zbAhF{(bi;u~UAQP7Sy+er44& zVwR8?e>SKhG86%+h-~(ly=laM%O1%e?J8e*O(&K_Q0_V7%A`e-K-2b>Oo&}KTpPvq z>T3-)0^>v>R$9KUiIqdI;W-Qu5a`%oe6WT#7?Ak-infG*;;y&1QQw*4I$Yn&1KUhgz$x6&qUz@#d6JZHVtbZat_6Plz~ z)MXUGo0g|72GE)#huE#uH)(RMb^_+kR(<9@1oLdGQ~9=SbWB)7`5@G?V?}fhEvnIL z4tL{(Te^C8tDdE*=K8|jWO>i9s253tEMb$$$12Hv{Hs*V0Yvr5DAv?Bg}9uW==PRi zytCZNDpS;($uqx=l9@_RZV0n+ZZmIcNrT(EuG~;9z55b;$;+K>cIdY34q}XFqE(=ao$hLS|M0prGbvbVdwk63s&<1~orBn9o%^zCf2CW9~2)_;?+Hx9C|< zn3A~$I_*;p`lIkbr_rJXMe;T$naLdoxw|malY)n-`%i;80YQ4_vMwpd?QNrIFzyOy z8AAM&Z`S};5pd0oSoRg!DwtM8I>Y`Iukn96)K0z!Ysu}8PLii zToO|~tDQ@Dg~zWyq#bdcHZG#)LCKK)3vwSQ8`Du^r1sYGlyja{vU}RdXS*1P8|6Uc zUuhv$?zCAZKvu{wC6b_6Dl-xxNtkSO!~Ae|n?0|3P}-O(A|~M6{pthc@Z;#RrkeOP zk+g6GmwMr%U3o`30`e9)i~QnYnnf@<_qaKuFt%i;wAey~(y+MKdS)qG+8ZB(`!H zGTWLJ5p#R{&vA(Qc>D+#%XHsmbYeBZ8EH}=m#YXRlN~^`<_RxeV{i{jB=N$%9VUrNVOg@Zhga7a)&CKFb=##-xas6MZq`Z3=_&UOQDM z46d~s{04`UaS3^`=*#n8I6iITRU@*`i2liL2x-}RDchyb*EFrgTCS-N&%i)8bM&t5 zc`t#Md+5-Ips2Ld7fV3RboFZ`tR)n>^w}En`$xGSlVkh|2E7_)kNkEAmFVRX&)3l1 z`ldd$t>nTP6w24$xO016<4L=cuzJWtibfo9o%X}Qf(EVfHfR;;&pL`5GnpFm^l-n1 zHd5Lq4bnj8U$p(7i-1qF8G+Td(`?y@t$vMw4-PwXM`0uSyp8B9)rjeY=tkd0#3*gE zrx7m}H6rHU2u5J_R@sO`*yKl|t9Q5?m+o82{Q7;vt;ycGf72wl3JoQMAT77BI$(UX3wE! z_xVm~oplUr)v37EZFsW~s+~Yp6)$Re_YaCV*(>)D+|!nGQQ2~>Wh~sMxeS3tZkdMU zKxb=l%xq~%`{RIzOdG+_$;mAa36@DToWYFA-yZoL!*JV`>200u0#Em~(vtsV4eaJU z1N-!n-Ge>X<<2OzJnpX17@9rf#@&M93j&B3=%j;H!zDwy4{MEKsd_I-Lxvv#i#cKr zaYXCzV$_fI0#tR%EF#8CX=t@NS&G;aT`t%%)KZ)(#_?#>-#*(fZ4RYfMrj2M)-{ks zbk{TUL>{)}*12pWOFCs+AraZAtuZYD`JRGWDZUf2nXYcF7rOcoI&J1L4XKM<7GKTa zBw}3yD5qgUvF2j{BWCXfV)AYqQ^q@Kl%LJ$h^2OoC0)lYu&;U0G;$a2ri!|PD%R^& zRQgs?=T@=LgQgFqJBZTDe0$+CN?YQa)=p_lebbVZ*6W)#RDIV`+H&8tPD;DWH?5n} zR!~~O5S#jajzqw^m6ms}3_2r@mUrx*^8mR~dG^EYMH`i48?jM=m&Af?r{8{)59KYs zPE8uX)Im}?wIAyn*-dYoe9A+t2mc!271C@`_gdU;u|K#?zKg-0$5MN*6B__yEmQ*b zC;45_O{^de=Qos4h93xt4j2fm#p#&+i`yJ+M^wo4I@&-I&^~+{sR%eDYQHY>X%&2* zD>y+_AY?if?KyVdZPg4KTnOWUJ1<2ZRYQWd{ZZL3YR4*{b!!!ZAR%=N$kK@{O;Hu> zr4qOpC5beaONyNXcBX8ZXa8C7aIXWhBQEuKQC2Mo-l=kGR7NRX4GIejkMne~#T!+z zA7|xzJ6bK5W2B_vDHiHYTo}IS$DVf9@N3jjBU!gDFHf_h_EFedIOZfwXs?xpAHVc< z94M-66Dw7|4jH}BHS)xvMS6XGr})K2On&B*5jxJK*jh5!q)%KES&lDas=c6lNYChe zyIShYgBs*PXsWCj?wy71`Uccz&H0N~-_EzH`Bv23PHxC_=3BcdVi4s`XrPPI#kC+y=NFr|DOmW>iokVJenX_I~a zk6A5sV2S4}*xuo+I6delMu)n%=$Ia~4UoD6$IfiOz*}C@F!o`vi<$V(hBqo7?(R3x zykYM`(!Q9l9sJLBDBT*c8&kta?sz+;C!VL`JdfSZ5@ch(_Bl~ViqA(?4e36%Y$aV* zo0$Eka&O4OXOgUF!$wbJZOz=5mM~J1L2mECf3j75Q_&ZfavJ+)u_E?d}$s%C}kny>iOLOGfIbPQDW4<0lqb7qY_Z>{6N zG}e+?t~w~DxQp!Vr&3h9BZ>)@il(28%6c=zakZ1**`9a0GG-qfa=mvJ*z+;{>i{wm zUemdfuQ47%K>Pn+veNn?;htE^V` z(kkfZWp0uhgE&!;$xF)AC6I)ZD>nIHbT@?CkpZ`~Xc9VBl#R5=DA8X|U&nhesb6ug zSc{I=($Py=`f2y_LK3O65AC1+gD+!RhO`OxEjfltu9qbTz(6-y%V2YE1w(f*hmnq9xm4c%gEVj@_frY?pBx5RhD_^t;*+E zlaqO$dP;4uzxYw9zMNA?!~Z$g!}C0hlV5aTo^|vt?Rmv|r!2(gJ|9vwVRG1?ukEw9 z!DLnn>7v<9KWn}G-AXaPZ_H}YhEl*+q>+C71S zq9kTpX`U-e(jD_V77xmTLA{{uDR`Z?AQJ61Sx{L!Iz_j7igtR7BGEqBzs}8`g6-ad zNVMPX_AR*4Q!wc*h(!BQr(n5WaGR%Kx3?e??Q5KZA-y2Iq2?4^;w^|oyU8ht(GgJv zSzYL4MbO?`W<9vm@KQ43sb#6R79`p)r3V#X;9gv{Oq^9?Z%E6R?@$Xi#j8|={WE;| z+Rysk8ja6!ro46tcOk>K)!VEuwx2=@``_PcXad*=SxxqeLl`p2t zw!kSyI5qQwA44K!jUNJ`KfWUnT0Kfk*cUCWU#c3sO*Pn%4K4}%sG)#g3E=0BA|DX| zl{iU=mKXq21sNU{2)`!7HGr)!u{a!F6BBEU=0F`rlL%+O5YWidA_6IT-Z}cA2iR_? zlG?u*aj?bxH8gO5Ze;f9XJ&t^Xwo8~H|z-$?BfI7A;1nSR?b!&oE@JNFUkB$*IW_ME8E+zi3 zACV3`4hR&mXDGnU$6y|sJ-@Tx5dHA{TcRJJ(*&&YGL4iXyhMg=;>d2U+(gZiu&NGp zQ(c*%Q-<5NKvGduj3FK*-5b6FscAZ)8mOiwhj=2Yu?!;N;wrZm5sAl9GEGNlF$s!^ zW}opezS{=)!gJc7p$qCtbmhndtCN>^v<%}YSL-$!*=3`B+A>uD9-~i88Xt%#++r+@VY_pV$?C;za?zF1-;Xd5c%@q#}+e^nH?~7>=c}?h~8RJXQr#Q$~R-EC}T@O zMs6d_cp3|%X>c{Tnc|~W7i8j-iwOBOA3~n7H_5twga2{|TO44OX1}4~n(mJ(sshm| zoE%QK1l^ujwlWuKqG+^KF{DldNeNU>)x!(f|KsZ5)bbIj%6R(8KzDy?tM2`Af?OvB zG$gE8rRbx{*%t$>KVY_&P({HdZy?Ef^n2>axr7Du4%E}oNx6dQ*+ zK6x+0q|yMl7XiMi7;w1zR+R7Iwe_U_wQ&O{M4l$aDTluQFV(bz_a?}H5pl*<&ZIEV zxn#6_CM_bORs@x5cyw`&>Jc?;)U3%X#C?6^a{E{z4HGzY>bY!mw#A`k*AuCyntF ziH~XMs{P{_jmWfxT%O{G_CBxNtSQQf7gz)qtI$=+NftkOS2RRK5zq!S5m_E24r>lH zU}Rz8ug})d=Q&w!TcI)ZDZ4PChVk_vt^elqbd)hzgTYrxpe(0OaLKl4tg zpa?@!);67IRe+&@vNNDlhh_TpHH6#~A#z4}{em~&wXIbit zs!`!Jo!A$MN%Ig#ZgoA`EGbJ+(iOZIpoTgklWllLqqLx#<99c(*FHNJn38h@auEc?~np#&ACM94h>kLyS^dywibh1An~ zgjCN+b?7)0Qc#Z$ja1x&)RIz2ZQLWIwv7;MGOeiaradbB>k&NXh&A^(%uE)~HfcK` zXR&PN(|kUMJhY~WpzNeg_M(CUfjQuqLsf+!8dPEFut_B4Weo;QZUY} zSyU$jV~~PdMEpc)Zf}*z8?Q*@ohO)R*77N zUrqAKA{Utzve!-*g&uP=Tv?c5`E(lMk+{#J%6_htlvdh3-5|>|b@snjHmE(W22Mk| zqrpjLbssEGlR{px`_ZqkePK+#`b55CV(iwunS3k~LDA|0uq&IzPA4N+m)9?k5ebV_Iq0UrGR1RpjE5Uz|%to z4aAKlIYgo^)1axOV~@yStekg;`?_J;9*)R@`?8BwE7E=77TPwpFr^#CAeqvISbEDi zMg&FEW55p-!f9QLgNzA^8EkP0Rugi!lQQf{z4Ix-J*5_CfsAk8vHaXZZmQJxp1ooKqh(uFAMo&p9=U#X-aIv6Xc z@ZxhF0eO)xhRhI(s~fcT(V7AKXqZkX7(-%?5bddx^QEt%I1xSE{VrpCnZ!Isn2!`i zE@R9uQ>-U&y)2x@s1&_;nE*D1x+lD*IaDD!@kWJ%wFJrqk(B6Z3FV#GPQ;4Uz$cpz z+9(nilx+ZxWYl!&^JLTnpF0aO&7&$k@U7-h4Nav5ITIph2#m^T#u8I9c!{*CZ|_^ zeV*HgIZB{G)r)=s+ll|D*H4 zy)W6nt~K2|lZveAI%ylM41h3YY%<&w)%}Qn%6GyK&JTc_2R5r*G-? zp}Ca9Tf6)w(@?Jwp(9Szz*0B%I5y~blA$Qo+^=5s)WO%A#TG|P7djS4{`N+)!_ZBl zU%IB#t|>W2d_X0W94S67zFB+(b8`6*^w1vV#ZU;13>wY?L*#J$tCjHQg5f86cY%>S z7aY>=$mR|Vk;Zu0W)O`X`e6^X#9-BAryLUt>_u0xj$A;QY$U5JHtxr!VG-yU%}tQt zk^*|!R@fMJO4=-;u_8+pu(j*&P;FCyX9C9@YJSrCknfAK=Z-|a_V_2a=eZ@!xknfD zx8usBF<)CI^ESxvqfa{aSN`wEdwo>W4laq6MjRI-c+EyDff(QH6O@Qw1xj3JVHUOn zV*5+C^JqWTi7RV)o|w=mfI8ZEeZaaZYmV zj{(ZTvXBDcYfkI2Zv)dsnd!qy zlZ&tNaQELBKwkWWZ$5$n1X1p0+;gS1p%5TP!mNVp#nTkwTY?-P@2UFDFSqBztGfg3 zXPROo-!(`4i2X-?i^v)fJK(DuF+j?o^8xP=tRTS>^^XYOver<5k^+zb(0-N#fUJQU zm9;i}%eS4Zvt*r*okextrHYW~9Eio~iN7mU2sR-;v_q??v3SGf`n6SW#9{ zZdUyN@6R;NUeHFT&ooJ+X&RmMe}5PM-jrpIJky~e#)=UvD}#V2D>DVWGBy4^q7znU zTMT!tEPh+5znm?SclO~dN6269+Vpxd36R%$XqiEi+WW(Jx}zye&e#b=u=!3ix$@=x zsEialCmhGOK)9mRr2e(Q2KUb9aM7)l8*ch$Vg_%K)+}ApIHeq;@6>=dqI*M`8$oj6 zPQx3~ePxi8r-&%OdWQN6cUQRaV$45K;e>+Wo8hcmhRVX-b44h7tDC_L-*lZDst(^g zJm}QP;^h1aC!&%>%G&^OiW?giC9XbC27pO8{k{t%fQXyw-0URfZmtX#M0{*I5hg`o zCeLnhV@dqn^d~n0f+>9SEy%W3%T`0;$_<3Ouh6gop>Mj?%?{2B-;DG9Y|GQ6dwM zI?6mT={K=DP|7|`_q?zb8>8V4hi2k6PD*%nODH5EwPe?nYZbTC`odGOl%lAyT`a(d z=^#1x>Uf0%?UHird~}esNbe9JLkc7U<-9$Vp^6OaTaQqy_zqFi$ikXBL`@@{n(}2% zC2FO^zXINfj67IF*m5d!(nH?*C~FhYh5C1UBXZgv<3;NCyMDh#VKxYF{a{t<+mBPo~owh8MPK zCAZ4u<}Ad_YxwV90S)Xb33e5M4e7*;Xi4#l;5h!aiAhxKn32_x9T!n<*$^SZt(ky;)CV7Cv!u7X?hCKJZ+z^L7;*uWZ{YouA$cqSQ7M2-K2c`Q1)@EoKR(VjH zRcC+y(ZPIfl-@Zpb~K=&l5A}11DC~nYS)~{CqSxvzV@BR=t^R(z4UQ9C#n<+r|+Gy zGjCVcEB$U0DrodCede#gB14Kph?Lk?OHHxlXLT<6OQZ9M9K&MU)Az?qBR&vX(@$ zC6Ru40TBtb@V`#C3Cfc6jC&t|FMy;VdW!&_uf1W_c3qpVJiH(Mn_YQ6{pqQlB(aF( zYhw?SUx5uj$MXTTQ{99^Ibjti9OEWbbHd#}Cr<>o{2ade#)z-Q^ff|!rSX-jnK)mI`xhf~(=lhpA5)NcP{wqXw)L)38uHWe(_Y~-8 z8m2Iov@aXXt4sPzWu3@j*Ym~MW1WqxG)IJxvZ!VW zRRex%Y?fkU((`L$RHpNn+}mx^$p@JSw26Lw2s;-l%uZX@!D~t`CNoEruC2j-;YUOTnXixY)#XOf$`hxt_qNc3879x;8Y7hOXDV4? zaGZw~3c7sxFIATx2FZup4Ul#`%nNt`Pl@LyPlSg}C zHHx^$q@29!!R^wK2WW}zSau$D2Z+5}|3tWni7Le~0xD=HJSJzKN5A(}jhzFMpZb7j z5Gh*xlJeB{%wZymQ8ilj%>q{Nt2t;fXY6(}W+gt*$ao3V>}U zJ)6fkRJ}&Mgnr55mWp87m6Difnf>_oyclUZ=g>X~X%s0s4Ze&zEpyeWxP=~}Ga{Vo zCej;mv`?=3^PGGq#}Ns*E`HULjxZwjPmbgVLlby9 z&~lCvrgXvSPO64?N&}q;8PqB4?VS8lrB30i!-#G!ZnmD&wan(B-~3H?=mHF znB)m*E``<7T%?mKj8`U0=aSGsQcSW*=gQ%lxQVh0b}{Y5CvKz&_Mw}8E6{8`OBF&G zyyo*Z9{!4_9$XoWOSRo#o*ye@r^?-xwD9PrVBGNr{IS8Y{04>St0r1SW2rb@iln7f z#Qv8Y1agK+juNO%2hMRx`Gf;qHY!1l;<#opipUk_GMVLeAYk8bGSHY@9JH$Z={}pJ z$SE4iEP#$x7)c?;8_0{kH5M%lWck15dU`&E6^B(rk$ZWacmY zVpqOUe~BU4Gsjh6<`Y=aP&EtOYF0kL)hx(9u!_<)`)86AGBfq$R|aeWlo(t9^g9rWu5&6b@o%8ZKBSD z!1bL5|8e0fs9KKA9$uy@O}{#9{)SgWYxCQv=I_6!)tq@x)!Zd(-Y9F{=+;b{-;Gpr zyQn#&4heagTO}Pqq|Fkk@S0`xEf5F@1V*mSe?kb<>Ij4!1PqD5ixPns3lKm! z-;2eEKMq@T9JXjUY;kd@T$_KFaJX%&hC}yOg~N6CGY+=I!8W|)CnZU5FXKQxutZkG z<=CelzgjCfjZC?fQJLTn+9AN<ND@5;+IUH)?>KQiQwi1(Ox0YJt%gb}&F=BC81r!kWh+o!4d#@WM@ z{KvG5d0rXD)acU!Ene#4V%80XZwUvah)Iz9C%Vyqdk-*HUu}?PRzA)+LVUvJGC~Xe z8lJ@?m=0A1A*w*E0>o6#>;8q~_&aV@)|WMv(^gR|fO!`PP3u zco5sgO(%HM z7zOc}PT*zmBNK?2pNZEEji%cH6P%3c4Rz3nAexOE<8w^I+XoWJxM<*FyrL%%0~tKKqK0^Od5vru5I$aPdqkE6HFPwx zfB-@7i7)Keve)M6N%Uy;;Q(bp>6+A4s)}@9{hcBq^|iRHfOcz5eZd-LI#O0e=q}P- z({U>b2Q}7-IG&#z?`dYQQjNSNmHZ#05E;EUAWH+<0MNM;ySRP>C>&Ra!oi+emr@b? zP*mD8uRhU|xr^~rw1K!!PHT~bP~+N%Mrt77J5TsVv&xx*ge2y(#?K5X0Z9B#uLRTj zdBC(1n23c^C#pPW zcvb^G_diI}8dzjz|0E{{L6Z5IP+Z*+*jFx50=zO}1yRsZI7G-Rez^N4>TS~8+5xDK z7A;cA>1`uYGh`qZOmC~=g$;5BDd+fgRaBbXz?aw0&x~o(E9Dzg3@MZf0wdZkRMxBb z`I+)BW#`b<2``kwTL@lxbWUGqgW&(~-J}H4`DKnk>S&-fPJ)LLG4hHA{Ki834uDj1 z&kw*=IS;C3EOjuhD61II7Aab0{J9w?ixUDb?7a--kfo=?xXl4?3wt7)uk28mW#Q@-}C z+qdUcqtcDW)nhGl?qu>4ZFIV=qk{(wDbOiTPGD0LgoGoqq^ezTcM5RKa;*?R4Mem^ ziXWU4p>-k{b0EF`DM{3%_|6^RWU0|Bd(zEf@eh*FD;TG9nrNJ&`}E^?Uf&k!`{EFh z9mKLN5VfR^Uw6k;(4%TfPqkt9V(L;94nJOJ{rT%F1^&v^LT^HcYQo+F z0-Ynjq&H!W85q!;Fh$}AJQqkj|Mg6@i)Xuwr>j~1!_ERUUC}`!iO8)8Ohy6?z^;K` zhRv1{b{jW^4g2VmP1ojG5cp9M>04Q&{zZ&@jd1AP)QDeu4K#E5QkSfL}?j0>Lg;Mm70;Ri8^wMB25jp8ud)%&} z39$S6L#jN3WUTW8h3&J@FTYJR91H6y+B+wkhp(Qy^l7vo9YJmWVfgkjYW zmHP+x_u;n5{EWF$M5k#2%30U}dU@@|2AJO2OL@wah7ok$kUkc{_0w!p;7d*F< z)wgl=uJji;$nQ$?JB1VEktRj0;|)jE_!)w-uZWSJs}tSWf1F?gnNp6F0muLpv*-yb zfl|F_5tKNuV?lnA2#c(LzlN{oWK1?#$M^=M5Uup9?r#*3t{0H9YE#v&Ufw!IhL%uB zOipI%xSe!{6wOtNkoEQs4xwYB0`3(W+%p09{F5Z^NiC%jDI-zimv>)dnXIvaY8)$T zlwzgFY|-FuIbOicHOm^$)KZ>7${hk1GAx#L%n^0uQ-=YPpgWyXiejf~#lC}LKNJAv z1xTluAEF0JL>mdw_8cSH2=HPSF!$2n9uK%Pf#^v^U|u?w!Nds6VG>LXU}6HyhsU~L zwjL+I>^RX>m@NR18}=2sKGt&m4!J%Rx%hxf<-5Kx-%pY6xf3PzLK?bDkg`UkWPir; zQF@$)Sfhs6W+djD9K@D8h>e$sB?z&nZAOfYJrb()?I^tgrG>nhjEUyywhNw` zwAeHf;@^|v-{hN3W8p2P@rd}h=@t&Zaf{bR+TGvLe0VupMN*x&cEbhmX(v<*vC11E zGkT}@@VTJ;kv`>z&(z8v_hbL^al9_}?k(H%E!O_4qSa))shgX8LjEqI&U&vw?mFpknPTwLcSDMt@iYu{MxZZ{o!TJwk;`cxS-4>JwO5kc z2?i;Rm%JewV>hzRfU=*G(&7`k4ZA)oOR zDN}e&Cq}*qpUC;THvEi0QPwGxH5Damq~yNx44%)}?SH0djRty=>3=jgEc>;5X_a~j zd#zTQD9q}Qs?>He7S!J_Zy=q6h_Z7N*$W$PfIBAZ3#d5X61VRdWCsv{fUVEDlTB=W zP=y~p1*ZM!w;S9IrKN8uMS4_m5qb$svk;whrkr!)&yY%vwE%GXA%-|Ds!2YOgMhqYDnZ^$YmkDKJ3|zb1qkA5V@dfa z7x>}ql7<5(;588yn41bIAS#kZy&42%)-E|mQ+L7WWK0gy0 zvde-6UG{s!zsuH8mz^sEP}*FOI+eR@CK0xUVTzqoWn579!J`Fb-<)2u&w`#l%bi(3 zXVT!D;a2SsdW}x#HGYI%qX=D16cZ?M)czRl0<#-l-9ffcaXT*1Q)Nr_h({|HVOh&} zyK#|TZuico2;3=j^>njTT!kBVtWu#3w=~BZq3ib}DIrz{}kU<`0PrF^0+D*3rHd^ zFjA*k(oL~E`RX-zUC|(F=-^SSUe9dCmXpo#n=NUXDv5Jr`K~-1%h1SKAl7a$7BrG` z{!f4(SiVc$98fPBd_F*HuNcfr0~8_wHoc-l@Uw3cHwt38={j@*1gNe95(n1)hvz-8 zERsfAKbD|>BU_}U#?x+#)Ipk|-l1_Z?Wn~`+@a$EzL~e5;#lmR!$Sc$llyFM#`i89 zR7;PehRhg0%vqy2?-Ht|iH8ZDF~jW3X!6>|Wy){Ya!6lwrbdtz2VEFY6O~$f zb{Zwup1ic(TgJtxL_AfVJ2!Vu?v#R9TIWaU{#n$U1j`cWTG{JmG+x%k@r%lHHM#2S zWth#Jmi1Kq&wfzxo7ZipHTZjTsrC@T1hH_$a6eI(YF^qhvLr7H+H(ZUPi9$>`Z7!$Du8Afki6K|)mv1I3uYHv_ ztwZ8HwNnmdgwiI2xZZY0{)Ja@TWN@nnh|IK?{M zBHLl==Lnqlz}wNn<7KQhrk?%0$wZ(SDQg}TBA-a3^s@1?4Pq&9x1STOlKU-mZ@}r^ zVnCR?gpD`YPP6IL&Kcc*&+>=%A3HXa4z@({)! zE?hBw%Qka3UI{=GH^7JQlQ5zxWq(xQDkX#}%{Sk4wn>{2BifQ678#I6pO)D_)_rvl z1N;vmo?^C%U#k<3N5HZ&M5pig36Mv1dS$>xCC(P~tKsR0gBaq=WKEpK?tYA9_=xPQ!vyG;hq*~{ zF3n&a8)T}ZyBCg>yYAdj+bvDZ2f|4lC zk}s~~fZbAhVStSAdTFG!aE3jhis-dwt8$4yNzU4l_pI#A?6>gTHKg%61G#(Tov$xU zG>!1%T>WCaoqYz3Y0N*>!i{PWTF>uE*4`R|S}{?t9gy>lI7g+SgrE>Ik!I^z*a0Ga zol(PGu$9ov)Qu4J&O8tfk({0OdYSkH5*>gR(^5#Z41Wpy+nA1RxyI6nsB%5cpz ztXSdZRp02{Ef#$xx@rt94USej=0tc+d0bFyoUBMpjy?$f3W_B}HuXUqSoEegQ^Ef3 z<%2AME-b^PzOur>;7E?LF4g6+J!2=lBB9u56?GYT!)X`Qx35+E_Qd>5W#a#w>Hc?H zA=91Z&vd_u7BJmJV!HG8a+q$}{}ZPB!vyLE-dI{=dQ}bavP4ab{GM%fBCpd^_kE3@ z_kiQe+_BEK)EcwIQ(9K*6kDhjBl|b;OM3y18er#iF1X4i4#B6;+e%j-<0h6biBA&@ zaP@dqT+H}g&l+;>Ktv{9nH%R#4SG_u8+Uy!rVpndaahD*{P1FISX+9`i}&A|$D?u7 zwS8#!tB2qSU|IbWA-x*-qKcPoY@##LeC_uZZqM@u#HSwwCHq1eC8HPb5hZb)L@j8~ z9wmMDQt`}uzMa=$A6-2tSEdKk*D}gr-4q|rwb9~d(kA=r@ucC!>ZnjZ<>R_#6)kMc zpZ>42h*}|+I-BXYlOE!LiDiH$hgR0>udo7Bd7>6koY%MNuU%Q?SG&7m(0gvc^Y=?aXM0^xVI(f-JH- z2^oB3#|`pn2w*jlZbQ(#HQ+YZerf)oQZqdkbO~s6t~gboOpiMsq$1<6A2FC5VrO~K z24(u48{=f5EvK}p{;xQ%Kkzv@??gRPa^BH_p*im)dK_XI1+1B&c$u;a7rTPMXJE=- z5K~@MDVZ{P!~Z2iZmE;+l?Aj(Z5bixbmyk8uxy3&$sOo4){|$YmWN!H1RVK`Pbq)@ zTh`l89H9j^}q@_C2c1Tlj*^9U5_6Kc+?`=KsV&L_D7Qdefw9a5>C*!urb z_ch>g6;;D`|B`K*bhmBNrlqtCY$4DBf&Q4%)@~r+Ed<>c3PdRq1u;t1NOvK=7D(I# zv))FF@+$fX_Vc%ZNKvFIR!C}T3REqqhzh;|_4O``S_LI-Y4@A+Gjr$O-A!8&e7`Sq-Pf*iM&NmzjuYh;{R0JM6PSYX+ z#I(SOzzTh*Qmv#thSNQ8IM@<-kgioKR@Fie-9bHyRZ$O#RV}LZteuotv~~jV(Ao(h zt3|mB$BaC5%&KOW2|@B%b$fkp zAk}^DNU845`*fm`LYcy8)~10*d0Ws$3U3-1H)Xl%X$MWwjCo!u~#G6;N*)9(;It^}3Bx6U!? zTjQ7<;c!fjV2+6n^h4|Xl6*g+ldn#-Kuz6-<9Dni^@byq0pc{d?in4AudE_HrJ1`$ zi?(Q%W_w~)8e;qD%f)m}>j4A+-b`_4Qz(XPJA=N%g7N_g3Z3bK;Mj^2ev`pIJzvj6 zyjAez{JMNvC+L$zv+1j>&_th<7B7{_t@!Q{31zJT63P@|CsmRe*Z@iAf>jT9XreMdBGi!?#5b%Wy-#pw!1e)N#x&%! ze3%K|zBE$!{91=a?_v%X=-(W3>8|TTxpxORGbax}AF%fyV5bgv0cOKq_8-$On%Ilp zWlr{#P!9xk2wJD?4+1bRe?5;!!R-X0)jft1dkCG)n!w5xzgR`QLW3Pt}dIUx=h(01YnA~Y~ZO}�$!CU(yD#P(zC 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

d0dUX#5k! zU%kO*V2(?`rX*4lGT`w|}c*3RFLlGTv-%)w2TtS1|Ch#+--j7V8nC zMX<~Z$y|c7w~_%!K5KG|;-AbOsr_-PvP>JmU;eiG?e9-Q)ls7tu?(9ztqkBy8-{pY zu%Ir6E}9!a=+dWfi9rHL zddCpxAY|23Dbf-xDiRiNxg*7eG{@0a)fA@W5fvO`Ax-ikz`bJ_#o zf2%vleRhp(=0AsO01Ary!F;xn4@j`QptvkJ{HtZ3pqfTNUO_eJ91xg+pN%5QQw(ny zd=PkXwF%LK!ppqj_VWom1MR;W+mPhMHq1}X<*dS}QW+5ppf|!+{#c2!B<;gwA9IBLlinQ;Y@0chV52OP(o)L-;FR(79~-G|vhF9lB`P^lS^ zv5`ul%Ib4GPK~l~lTw(<;7-3ul)?9iuoMoadH3d1Yz0g`q6_FDf(S*spw6mHI^Zs! zPYpWLV7kzQ-%V9%AiQE%expfv*Tqq;OUNNlm;zx;>f{uMb|7Ry_K3dBg8euPjZZ(K8Q=B) z$()F9ol5btm50XHhRmcD#twvw%yC5GJk)WioED=^Ux?ygxaqPBRzOC&w!!~_TT|{A zebBI+I%E6F__yLXrrE;A8q=K?EkK3W^A4_+##EY;)16`Z9uMW#4OVk-18zz%Wjh>S znb92LI1O>kMbl=YrqO`#u-XT={LSci-t@iNsMc8g*3D>u1$o!GVDl?-t*o2~dwzHm z2uvwgAxzdPlBllbdaIVBc}8vrn9_KQ7e1?Z)tRZKA8FDma~)o#epg-3oH%aBp8cc= z(w)%$F5qv1p~c~=c_lE?ObotP<;LQfbK&cP+}I772z

y)MFgnK$SKCZ$2~F07z^JPN>BF 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

`zP6l>RdUsW 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 bg~^XAru%)6ZLih{76v&gZ$3(GzZCm#c@76= literal 0 HcwPel00001 diff --git a/ext/CrashServer/CrashHandler/SendRpt/dbghelp_x86.dll b/ext/CrashServer/CrashHandler/SendRpt/dbghelp_x86.dll new file mode 100644 index 0000000000000000000000000000000000000000..62d850863e6a377d5c2534142f07bd528f9d524f GIT binary patch literal 1080656 zcwX#%2Y6h?+3wiKwzTUej4ctclVd<&Y)QxkV}uP>wPjQmtr}pkR=Y>i+N<4V&#sCw zV7dbiF<=NGggBvx64M>3DG3lt3>ZQ+riBis1WiQTNpJ=ANLg zMq`ogn6Fp$`@-Q!TuN=n232u+_jr_bzTN z<7Rp5M3_0Bp3*v!`+d;*9Jdd&j^*Z{^pCV2!p)vm4dy{dU)*{Sx1TEgS97x|=*yVq$!MDH4~XXpRudTCbEU(Sh@$>r7-L2%441an2Yyd`(J=G zf$db5`6@kggtP1r$$F%3`(YDVM;iK)xHb@n>8+nA5=40&<)l%O+me7U?!*0=TSthz zFNLLPqJwTRV_QpNdd!b|o(JTG^SUgBZgELW3q?Tq$fJzsjXehQiWIsE_W!T{qu0{% ziR{kmiR=oX59k3}fyKZ~U=r|c)kO9Q@G9^Ka4E0`=mFY+BY-);RA40VdF4d56L=c9 z8@LA82&@I7KnJi4Cxzl&W#F&C?Z6el`M~Kw2si=o0A;`dKpwz=PmqTl zz>~lh;2PjUU@Z^^I)PST0WcMq05IU|BPX&^i;+iQU!V+V0y=;Yuo_qgTnbzR+zvbh zJPYgq-UA-17CQS0c)bn02!s|P?=b%g+zs3a`~kQWSPz^6#DSGSC(sNm0~P}N0{K8L z@cj`J*}s5)0ckCMfH_n4nDfYJ%eZW`gqkcN3KD|Cyk4 zjF_m5_{#*PeELMC6F39d2wV*qd`{jx#=JM$bZWt=-x)v~IWRDSEysO;1(^>moW^4K zMF5qRvH?~I&^3bfuHCsOQ%1sk52gY$Z!%Lx!7PF~8fG2LF)%|gbEKIIb3IHK%zI(F zVZI7;EX>>~Oc@7r2F&p=*T9?rb0f@&FgL@@gZUWDJz(yFISHnk&y+o3Hp84u;b2aI zc{|K}m>%Zz-vA%-ujTye;8zbc zz)f(o)3&nNrp>slyy?iR&Sloi|lX zot(}%r_wlA((-6h-kZ35s$sU8`edZX;7O?#<=qSS2zcubx=d{bMnHP3kHJn{iUGQF zb3eMXW4U>k$q!>R{1`XW(abdYszcT=A^n&wHI=+HLhuc<19|y`;Ns(@Qz!2v;QmjSFEWOov{Wf@Z zFhf_VMjy!CDj=~&NR(RJnLK|+>srN2!w0t}P1j<58W(6~W7C{cb*bhHXp{_ArGc5~JZb6L)HPAQ01ZU2XPthIr;HB8hOoMpqZ{1=Pw&xGUJ5i235dNSLwao*4M5 z-gqSD>qaPVRPzUYA;h8kW5FmVs?s_W-NetQYibjX#YJGR=1;_eaca(4^?+X!)JA&9 zO_-jD9vo0BTd19F3x)%cex2Kl`z5$<0Lwm&X#2I8r&6s5b{AKN13_O{oja$vGe{XI zZ>l#fwc)rHQftfS&x3m?+T&Bp+dZ(D_n;5XUBDZ>mhh@@q(96&jZ3&fLAH@Z%+F<1 z7Ywf=sa8fhBO#H;AU%_Ke7YZEVD;r*u9P*%Nz4~!m9u7{x=n&q+4rkQ*%ps9jmG>S3Ok~%zI4zY|3m^bxn0sQ#Eg-s@pw{O=y_OzYrmLMmJVfx7Jp-@i-c5YRL37wpBNIDk~`Bc9c(Lbv0{ls)b5dv+_F6 zQYyguT93EJ)56m)@3~11qJ*KROIzxxhb^z4JD2Rx1?F9P2rv(r%ku@Z%Io2#5pRvh zN`r_G_O{AuV&6K4WH7rF7tDFwU`=y{S!?J{!%+>5Z4Im;qH3{NB&HUtvN));)qvIo zXH-*9pi|{F$>;Y|B@AfcAl2T=zF@d3q6T%n zzBuZQr6VZjZumwLajt7itLr>!Vva*s(=N1^RTQG<_zF5U@DMD?!ebSVai9q+rV~UE3g^36j%og0HL1<9)-G_wN@Ug zLT^!|RY9E^&4AslIxL;2?)x>huF<1*#eBV*nh5u!8nV)N(Tx{7Yr1U!bG7aeLEod!1=*8%flZ{V%MJaYSk-t$^#uZ?oPMoX>x?3~-Du#|!rJ-s2FeNtc(&2$ zXv5K| zmz|ghYH|Lyk+E7Z5@a+iYzO|cR3U>k=c;LN0*+1v$RCV4W!4}(3`ABvzO zEf%J(#(Oj)U7|aHM^FpLRUPd{oL-I6d(lKR;EM}gOH172(?O<%1y@eT??~678BCfT z(gJhXmGA-EFv02Z>C{l1_HB=%l-YjxHq1bn~LiZS3Otw1sUB_G)_E*Bdq5&`!iL z_>H0(QMtJbbpn?+VpTEbsV{G?TuN+J6g_b#Pm*3Hzl`o_9MjRVbhMN9{l%@Z8r zkRG)-wG`MMLe@rG0K^owr@`nJ4JN#OXokN?oYDB19MsN1RSQyj5x34;8cM2NAxlJi zAUKNFl{W@>P@&P2QRh@cB90{UzzDlg5FMc&Cp?cQ_vy9Gkx&4&*c)L7AIVrTFx}s? z3M9P!8K53p_EBQ6$lDToE7FOFr&YwOvDX(>E68TG51{7VrdqfFtd79Ho4MrxybOWJ zd0{bkmhLoQFXQ>GO7uomaD07}M#_ z%b%Fk8puc&Q6OzIXU-(3UJ9%uD0SGP{m?No8Kk1?4eC0@ENR`MZ97mlIZ1)cHVa)l zJ!NWgu*+pf0f>_fBkDv&MYGz72hUy_OvB!g=*4grsoyVz(GYB*U|17Yc3hP&?z0Bg z$D_Cs=1_;%6?$snV>JE}C1D?@8%n~5>MDPJQk_>hZ&WB+k7$O72cB)K%G8r~w@Eyi zGUw$j95FOm7wR_NRLJh6M3DP&qN|{FO)zFktcKuxPygHC@H_EFRwj3fAa zBft3ZaRH(dah(QGLJlxiT4gFkGv`vgW5F@ zMm5oh^Sri}tEwjw49B$?*99qpN{qmurZL`97Gp$?5hNd(99I}9!I-2oghr8zg9gTF ze7N2tST7imJc9(gT8*@%B$Q(Rn-erXh%HCJX zmFiHBFXri3{#D*YFQ<1~?sSn{;V#DPB2Uya zs$SVOhG^WV&M4Fm65;B7{vK2=Bi#XeUK-Fan`1M$@>fUl1r^+*TtL*y)Hbx1*VR_p z%TJY~Co_C)Sd8Yhfq2ZP`eNOQUM>Vs7V9DeZ~jsm6T!2%%SOZdB^v?x`)vLihSY;` z!;5HQxJRtQofriCBxy#~6Vg^|**&bG+SqsCF)Zs8ZWG zsE{q~+>M^A>`u0J)#hF%UtBC&gfbF+d(+HGGOuiMAL*y8%)gvMP_7I(o zc(_GA+VPavi{V93ytw2_s#3k~=C2p42GP$4{answ`qiqsI@Ry21w41~hbmATfz0Uq z5jQ4Yrn*x+5N&TTZg+>wqUq?lyCi4wGWE5XE;X$6i#rNuX@;98*U(KUa(9@kFL&nU zWOwTUX`)jf#9*kG*EP7|X%f}g$2)N81G(#9$2~<(r&yJj zq&-&4K6ei4TU_mr#4wN-4Kb@2#E=)tOZg_6@@SL~phewNkC@ZlX(U^t_SbmtXYViS zs6`JadON9^vw2hxX#PZ8d|9wQ0XV~28XXnAGL5U`xQPc9(h=NwB@_veYA*#YnoG1e zvRUJvX)8Lte^0LpqGOWPr^gYc(WvsI#HoK1qZjJrNXKY|E4wsVD55{Kxzk(n+WPV( z)o!PIb$fMXOLKVzQe}8M{86?ky!eQ-v0_xD1IM~!svh2ro&1|5`#M*d9PSNiA$IOPWjzu(L8T4(23d;?SQqS!`C@}IKEZa0 zN3~nYUTfJX3@QjJ&OF=w0^A$^oLKU27E}3<&+bIX$3ID>ufHK%gOFUAVpc8vPOXxBTzU-8g-3{cm}KSmUBQ7wRMOy?->=I1u4qIx?)`nLbsy>KGVaB5 z9ly+nJL7A%?FrBAPI)StQ5ZPL7*8kVH^>LcB{4A>_0>DZD1^MbM=GVjCV=jv@_r}X z-!oF#c8_r1d@tPY6Za)i!2@H8uojv-rz8;KZ3KV3EcEjD`Fk!omqTYU)+gs$(B);v zuzLK{{E;#|wX4j-B78=Gm`!D${UYYKIA^H1GxDKX88lxd#%HhSat?=mE{(?Bh^G$- zfW9BDVorj_XB~*yG!brhXNX74u=sJ@GV=>EW9Cd;aL0Oq27VV$7O_7L#+Vg18TJJ@1q0GUmi_{f_y)vA$~bn9Y$@T9^w%xS<3* z7{j0x`E(i6oo2Cw`ZP}7>LcMx9vIPa$2N-xv_U$Vc0=DJuWk&iQL5(GV&UErrh%7u z9b>rFnJ#U1{-(y;(w)w&*@wX!aun~erLQui`ND~)X{V7&8!ush8eOVRGnY_+3N-;y-$G`I06Mzd{&426Fo zWK;tAi8-iZZY=a}DYfQeVqQ%ogok2LeRM8A(vG=oj;)3W{V`;k8uwB@!&1!KZQ}Bb zn_;(}r6?U|E6P@&;~YiFTc;?Cfz3e2xr$5 zsK>|WP}*B!qi>~I#p(K3n&Y`NsqH?TW$u&H(PtOOa6AoNr`kw-u<9;S=GaX@v zUR@yCYP%j9V*;bz`+1M=m$kj=XI4$w}js6W>|`;6WZ3ztTEE?F&T5V zsoVz9`uj`?8~I4bcX#uXyc)s%-z2B>eC@iCyrSX9^7Qh#gvN9O`GQqV@P5pgk6av$ zMf!pP`8r$7myq*(tPQrg(Vo z>z8$hv8H&a`ox4U)DjNTTXFG7!+9N@&|-s)oh$K3Z`p0yF0~nc;W!?=<->O+9`)lG z{6<1OS|~bqjyLR!>OGOTm6y45YJxF6ZnHNS@4VunDou~aB7;0G{!*bL(bYvS_~0j4 zr+Seeca zHURC8@U%KpsmpMT71=@$H6Ax;hogzYm!7hMph%9>7%xU;Z{p+cV=_@Ob^y;&kdHsf zrP$^tRvsmXOfQG@w1ShL(KA5TZt%)PFZemrtn##`TdS1J*S<8i!k( z)GB({MRKB1&vN7^A$6Wc&#lb<9Jd_xn#zi554{tv1ov{pCdQ?9KcPoq9!jiNa?&>9 zj(PzP_bX%xZdQS&jr&u7M-mH2e^Ha>Be%01bb^obY129OGW3|9%8XXq=$iseJTn>f zJIcg3KGRygJmVUfH+nLgJOW*U_>E+vCy(5dIqdC|k8#+KoqU|#z9*Z!e2+Z&8@UJB zk5BSHA<4di4Rei7`i)8YP41ZNo7_3szb6yF(WBXv(IeR;BfL9z=wCsgK%3lE&~2n^ zg87@MPRJ|h$q%NcY4S?zeu7*4Oox%yRuSBPWYTYx^H&fm=p8j?6q_8L94UwvoXBz% z+H``AXX8drj!j|(dO^G(QP4NJfARoIgB1)GtS&gIU`@fv1*a68TCmp02jb`{wVLzkhyV{sH+1=FiAKD1T=Dto)+<;{1~QgY!!>hMS!~2mf>P z=M@}MFu&kX>CQx6k<&C+}q1^N&JXQ<-0tU!7l*za)QY zer^6T!*4jb4Eviz@lb428jX1KJ^4pFTL+oeQpb;FyqA)&^Ppi4<)7j-CFr0Lk|5ao z#W7MMX`u>Ed4?<|?ZN-^rZD;2gZ~!<_GHO4WAajRCokNO*pu-debO*Lnf?iroV+GX zN#O*1Hf8fBXBuzBhdi&0*?Ss0^5OCfwzH=fL*|s zz<0o?7N(2?CIeG}{edE29i?1Dpx02Q~s%0k;E>08awjfmeaI zfscSMfl;kY*$XHF76Tz54y*yr1l9u^fy;rbfB?`8+z8wbJObb$PRRxGfV}_}m;sam z3xLHy6|fYj13W-8&<-pII)DJs1B8Gmuol<=Yy_?Xwg6j!M}WtG7lHSHkAPhOYe)RR zWMF?_9#91|1MR?aAOx%d)&rLVHv;zpPXez3yMX91h#S}dYyvg|TY>Gs+rXE=*Ff&E z$SW`dFy{Yz+p1PnRnsm5C0?zY&lKV_+M~W0&A(Iqktm^KU>=m= z<*IC2QOw^2(wsY*cplOQR3i+9PlUN`wU}c_i^OO`yLj<#@Upx5LUChx2jUQWP1xOp z3uDsGrmMy*PgiUh~`Cv&$g9Ieatg^JWt8OCrAX|y~u8cOIY zEr}LuhLdP|BYouQPI1$nZh=UGvY*1onLflQLnfsoB@QvC4Y=NJ33oc$ux)WcAgD)aM+3g1UaVk|)5+vKf0}03ozTQeG$ftG$|sTW z$SnS8>34_LK{*6nD7Z=s4W>^@7U6zO7-tC8yi(G@1(?c@FP%=Iq?wj>dNqYYEaS<< zFFiMV`qFW;{K+L6iECle0uT{&pqOTK@>q150ADD!A`l@sjj`o|jFG>s=N@JPWE?)f zKhZ08btvO?p)gRSYC&o0!W5f6&>abry9kej2;p|{;*C;~%m+>W^j1~yZvu4jdE4dj z#;z`1iG>C%@HP8Q)%0f$K^<*g_~NKRp{0i&`T98&%w z7t+&cz2)X6XsT<<>%3y0B>o-FQn|u@eMowtdwekrWuSy+ndy~!K&WFTU3Jh`MiX?K zN?Yj*`4b`ZYBY?fiNtmz8dj4)Lm?OJ^#;R1TChi5Qy}3tw|^2Vy>*c$v2_b17VUmK_0gBc#I(4B)?S$xP<#|a;8cU=xWCNKY zOy+i61}##{D;k@cOESo3H~8qQg3*$c@EP=kma@{ifnoDOd(91%b9;TusJB_ACz!S^ zNW(uxe~;pG|E=oYPjRNH3%ow~VtS7+WNwKkS1{-$l><$hKN1UM*Y#%RQ@wk9to75z zfH}s4t9Wq2z=hV!_%RrZt3v!Hy?js-Blje~6kc{BTbz}i7Bx=GJCefNo}biyKC#)! z!JzAsU9(ujBbQoch%1RUEx)MPBPVTmWATvPn`U0}u7TF5h^`@RheBVFX`{e${8#ZA zT(mD_xx8a+fGyy=ucq)r55nv=bBPD|D&0)LnJbCUIgD zFgeX9X6@diC!&0-NR!;md%)yb$`>-#L(wT7(H|xF+DOBVw2n+K=R*50qJ48z-J~%= ze-IT+?(ZKA`$LHUuT#$PKt?i=-)=3eiA^hMO{-rEg~VBw`wM z6vlpJYOp&TiHVTL$b*memuO*HZb6HvymEzY zLxigoP37)|Ym6ds>5G@bkQy|HbaOChsRSQ5o9|Pok4i^h!WR!Eg-WBh!^C5}=`mJS zi}oR1d``Vh8y%B6Z^%P50j3V~b%j5+Cts?f=_LsjZDv_n;F2Q4Scf@g-x?aWW+%ANA`Yp>kS@|2{uiW*Ju zErv7J^20F<;G_3J+s>GE-g2+kc>8$daB+CF&P>&s!qtkdt%bjhrgX?*D^1-VuG#1D z1_B}k-#$!@N8)l#v(*~NekF|NOfqk-^CovccD?nYPn9cfy-}ZE%lg^RqmEIc00T;= zj!`^76xao9nl?t+3hV^fPsb=Kuo>6}*u!lAL_b)b7!c{5k)eK(bcMM26Do;JtWneC znlwFwUoG!W zS=qu4k)upu(&q|S8QSVqXn$dD0@&ebuMZ#NSlj1V=T`|@U=y&o1}2~`feCB{b^>`z z!4ue43;Qyd_23EQHNt+hSSzRkn}DsrPJnsg=C#GsEX=hqcL6(F5ML{Jw4sk^2aZ7; z$Aa#7gaZ}>9l%;(Gq4TV1$Zt&m=i#|0{*~SU=y&j1AcyymR-n;S_M0>7T8ptIsgAJ zfu3=Kz1p#nuyaM3)!6dgaLHa533t;%Q@K+BOLi+KH~ZR}Hk+NVy=gO^!>qM8hTT}3 zL(f3MjWNFO7#e@$B{|v)=8bg4Y0J6g^+A6uqQkb_I5wi8dAX#Nqif<%=QQn3nB~Sx z4GcYkp&&-ORUz6$|Mo+sE;)G3u7>NY+1C%RZT+mWu8A57u{NkStjFoK0~6P7#dj1v zOx63szHTj0WehMyob(c-A#M&&&9aF``ePV-b{YGQfE8_&6rbhn-(4tTJ8MIN| z7Y#}a!iixWy-#mTvX}GnrPYKorIduWG;ZZ-+~_rZI$Clsr!BJkegFII(B{7M?NI4yxbGM35Z(VzwL?@VtW|F)!&Cly z+TWe0q|f)JQ{lGu|6IO1PRlOe8_ss-Gw<>rmrr(1`h0GKdvqQAevUMqn?9er&K3Dw ze7-ZE8(`n?OZWrP4G43gGoMl1cU4-1Thl+0PP1Fzg6eAw3>@9T1n;OtDvmYq%1da?Y#Pb zUSB=e2z}jpZ5n;O?!QN0qu2k>=W{30u=pmV@21pzs(ZoLLuCaS-bY^wWqB`2d138_UzNw zP98nFy1M$Tv(6gLSZV26&)T&tm(4hEfv0UP%VCF>mU=wv5L}(Hb{)JJ>*(m{>FLSM z%^8SB`=im^Tn74FmO~4&YB12Cv6bA;huitsN;=4KUAeKt9qiTNzF;iEH=J$t#e!5l z+gOzrLT*K%dOR!`{KSCAe8 zn6eTNZ9Gf}&ujkPXwaTcJ~oqkJLpr>X%Kvu7%B!UIb5vp>9Eid!OGg z?sYn^P15`Nf_`7r>M#0(VLeLIy8^U>9k=)PO3#>2cl0g2Q8B#qM|u&D<*xT=A!B>I z?tm45W_22t1g-z?*JYZ;`Ef@0xTZf4`3_6`Vex7pln zzT7LMi@TNbvo5U@`e-fjiA?Yiu40X|;a18Pm~^5)2%2kZOKm**rC-14H^=nrlx{|N z>x{#NtOYHDwa!`Wk3?&$Y3;0iry^SE9FR2B>%`d+oTr!b5i5~tuOB*6TbxSS!gpUW z{AhmqO z=o=4JJPKpDQRQigh02rN$f2!4i=**D?;aMPH|MmaaVuy11rKc_7xasL#cX!sL;P&s zc6+&LuN2Q!v=^Gg4vM-+WK|+s?&lL7Fv^nknh#s*B93hw_#P^fw@#l`61u2>>D(!D z(RNB7X0(Y`Y901+Y76*K#|*&bENxQU%pV(!#--|4(!DVUvmzKqo5Swlr@>)rV3yX82a^1#-{TIoW)dxTD~#z&ZbI(DuJ?rcjrNl| z8qtr6Zj1y#Znf68PA(I2ll@;T(u*3Ux zGY`m}vT5#*0z3cCBpmAaINj;S<1{0by2fApHHMci2}L^jhQ^f0^UG5ccMSfH;6l%oqg`b-$cCq1UHs2~(Zt}j|PY19X zY3DiSGJ*^3tW2M5F~XsPDd-u_v5il2q&%z#O_e48WuMIHRB1E?6fPn3~LwIqKb`qQXcq_iA!p(fj4u%t&VRw|e;AM^I?RICnj8EUrII23kTY_Gz;#eV=@T=AJ zghqLYYh3lvd~^3DLxe$!`_NWXe@iWXxSIqm&KF^V#>0yz`YAJMCkJ-K_ z2H4i`@QnB$@osSg%$x z-lG<_i~XpKlNW4h?bhOSa7EB>9NCbLJx_tECP_jB%P5b^SVY&0>6uxqvEg$+i^SGhK} zrqSxS0WMQb6K^bZWA#!vLWiOdq=O}rF&||=^>*_%{%G#MZO6jZ|WhbB(=O|HN zGtjuhF9I-)MOqB~uGVXK6an87-otvx0O`60YiCRMlvMH@@<)NcEwr^ZBSj zI(me@>btGE!$CViCmoIzH|Aj;tHmNo1Y*gUCeG~?s}GHtx)E_AawjFzJnxCLUyD0e`tdg0G1Sh|^RUkCB<{U`={smLN)`*i12X ziz*#w$N9J0`5W|{M2F^R7`SDitzK#h!I2Mdl843H(K_)c45osDW*DLh)`(?&yk(+R zqLUw>LwAKkMkSYevI-jpDM?@>V-`WOph ztdY+QN(2pic%EcB&2V(>&ze~&Q&|b4lLYL04}1ByQL%69B4B^`1^GVZMwk<9KDxta z9x%)1+v)HX`EvHJVqP2R#t{9h)UWAkt+_7U4X? zuZ$+*yR9^ck+@Hs3gG#V~?2WFgZ zYK1G*hX`Vf`HZkdeAnjV3gs#TIuNTN5{8?R_8Q*O6OlPME|O$jlMr5w z$RFuTj5pPMfq;-}Ma;_=CBmF5%{kJXEls||;zC(U^bM*!T35-q+0sznOf*gWooJKp zsi7}Owc)sz96T{CKrfO8T-$QrbFFo4bv@=Hx^=D%u1j5;T-U+2|5Z$x3QPvZ0i%HL zu4Krsz;6-2?@E9;c8OcVCR(|;5haAR6un~$fawKD;M~@nnlS6)^N9FurTw}(J zVQuA24YdtR%2aXQ3?EC<2{* zQwwngtDyQR2BvC2)BS42yfVJ=&>~Wy5YeqbOTUO{tD`}bwIrJhUF46CoUpFCV)mQ` z)Qc?=YU`k#lZJK%jav^|ls*l!Gp3V7Asjg~8xgFN~D7l|Mi zjDmbR<(G@43F4-vbP??VBi?-pK^y*aq<^W?+w`9;PkPV5MxHlEnw93Y7p*k4x-s)i z&+>}e)HIWv#F_G*!|ZExk@Z0>PO53ew9-f4r6`EA4&gI>g#4qXq?$jzve6<&Ub zVT!wOPIa#l9_HF*y8`ewC`ArYJsRoik~v5xC!06Q%PIrWlc-hpD1w>vPfsViB9*6~ z&IFdalSaN?k}pg?rleW3k~AG{+PoZ^lovJ0e|{NSz7^du?q0-CVW!&wdwLEjQ@dlP z4{dAYAT#OaT5+LB7CGXfdc}h+5^pHgH2I!wqp{aHgf*Otx?{SpkBiSy?aaP$(|cCm zxc2=Vg?*5tZ2J&nv5(L%eq!~F(JylpJnGcY>6B>RJ*wO+WT42rqeC3c+at_-H#5SC z^ifx0oYYDyDQFA?Z{9SSK^R=jCo7tBAkTp?{h8Tzbdl~PPbiZc9Pq}ZOP(OnL4QTE zTIp(Uu)BvZk*CMX5TCxq`zo%BAsPl4FW=EXqnEZ`#FOl{eVe1~`qnwFSo|Hvs{etk zfDPYUvZHx)?F;795xbrAA<>ZiR+#qiY-Fza&1BcCTr0c+ca(XVQHvY{{B~2P%2e@4 zN~1qM^lhSYl5g9MSMY8cPw_AOf<_3+@tr~NYUCrzUfVtZb7aJJ>P)n=cY`*S(x6T1 zp(4g}DK(n|a{Ns1I?MQRyyS^0i$}xKxk*_z$Ff2tdVD$wubmILb+;K`<}Xujn~aD0 zW+iDX!SiUu3sH#N)K7b$mUPeTHi9I7`<5SaWs*f~=$5C}(k*ov^cCP^-a6dZS-MqP zpQ{YapU1?wmv}hk#=j%PGJi)a?0Qg#*g|=V$wk$21EQ4RnV`-`PWZ8vf;_@K-OWrtL@{H zP597`#&AM>w2cj&?JO8|NSZ!==KN5U7VVJy0)t^+FOr0AdmtF6&ds2r_DJwCXsn4N zrf-MVqh^~V8|{z@PnL%*P0swK$SniEXvpX12cv=&>A-Qvt8~_1BBlvG$^JIqj!17f z$Y0~>!EP#dg9GVBSnH=7S+;#$VjmiNGE7EJ8rYkfn`w4lNA*(HkqE@)Yd+{L{8FT2 zOHZo2)0eA7msWg^vdE}Eaw9F;Z_^Y}uP>TL57UjE|qt438O71ioigZaHq#KmiPFb?#)@9zGu!ylWzyZL* zg^Sn`M=WB6xIY*u24(>>iDnIG4uDBvfKz}O2hrIzj3Ef07rKymFq$8V@IdhqGZ})g zS#(dp->g}TpPg5X0FkJWC8d+}bUMN>0;Ur$FggM>uo^ne^_gf_tVo1W%e(O;jQg0} zn1bA+@fh0R6)XH9{=S^kcKP(Uu&h`S?+NP0y&eykG*KTp3*P>K<`2On*#~Bj+w$9) z(hMvG76PTf{=i;99xw{{`ZlJVw+~Ym{D~=3fn4Cdo0;+?unT_g0dE64fmeYSf$hLH z;7MRBa4)b0xEVTy{6|ev(0`>>?0vPb+tw=Ah71#u<1v-Gmz*K+%uik=m0~>(>pa%#5%Yiyz z2A~3yfl!qN-nADu~ zDz2gHME_81E|Mr_2U1<}g(Km?-bg}M(LZQ9Z6v{Y(916#I5i~2(~-uxFCymcHMG># zk*N*Pykd3V%6(OKT)Za{UUhsKxknS7c*Ydz#iM9kqa9OVjf%N?+{0+Lh(=akD^8<2 z^Y^_N-F0e?28vFX)2Qtlir(Jd7y(#vdy$4I(f9%@6ZER%Bx)yMQrl|3*9J}^x|0ti zsO%u*f@H(<6+wdJJguUIS|}8Z>OuVoR#Z~L_xiIrF><0|Mx-C(5nDi>bdn3N-YTB$ zjXSEF{qyJHrr+P=i>-*m9t_84&so5@AMSbGhdFnS^qVhCP;^GbS}w7RG-II%+FRK1 zVFeJGshEK>cT~((zB>&fd*cN&)rABYE0Re`V&wU+Vi*T>Si1(eUfX z-yh$!uBQIjv#V~t?xYPTPW#=OsWq$H$8KqEykMhePWxs4pZsm@k>?jAW>(&vGvnxa zfBfM57598L7{2qJrFULGrTXFh{vZ?6mtB7HQJo*`KfUU= zV-9bNpZMUnFTL_bUSn6VYD@0M6Cb^L^n!u+O25Cc`Ln9i?mleC#)%zGdZF+6!eCF; zx-%|)>ZA1wmR-Mo{(H}i_-*-(g*Z7~_{zUFIOU`M$@Uy9xpY!y# zs?{Yk?_53R%7!~G9kumW1)idL=k3}3)L_L?cP;z(>uHY2b;_eTUTC-E`6H z1MVw+%Ip2~57&KlTf>HDpJ-b7#KPAmf4J_p`unFE$>(2P`^VCf zlLpV-a#-ZJO&{)i--Oz0H_v%-`s1TQmq*Hfd*&OrR$sO2>7!3Q@rvK{KK{xHFFbYO zl0V)5j3m*h>W`RzyXr}tR0Nj>?OmrZ-N<@hO^zrXH~?Ge0tPv_m#hT?Hw1@oz=eAnkk!ZtlPN9#Kzlx^Ru$U zpP1dd{o^C*Zm62{=l{C$^z)UGBUth1QN=l9igR7X?y=*>PncNB*V)Wv^VlJ5K0A~x zV281CR>3M+6{}`7ydEeY<|;o0UYS2mIThw5z)ir1ALl9uSGbjbFLf&_?k{|Kyt43< zT%{InQ)=DH<8xd}GyiTF=U*CQ@~l(3Mlf-06-Le3J6sAi62~eoCFe_v$G2bPDwlp? z#gh-e`#;T9X79>X*8dmM0rR!5a+P+_oC2tyloQHa z${jH6?fCahI^TM%?c7aQHVRy{4@^#_CF69^Vti1PDpshOG<=9_m0ql>Jx|E{1E@j4S zml6lI0^=Z)_Bn#qi0k4~C;xBeI{EKci846cN%QeMC(TQs`2sYrEO05Go`W#0Zsh^o zKM5RslUvz%t$Wxs9R%9bZ*(i~T;o>0+|Q*Pus_^^bAfw-PXM*hr8EI&0(S!M0eeFa z>VQ*#P2jQDVJ_uLU=Q@qlNlZJCQi930QLg%fhkP9Z=m(Lbbf7+&nYt2y^8aUd-+-Q zA-)?!fYoAz!T4ScA-=kmPRQj`5#ZiDbKS0yHW4e6anR}7eR5BU1V1G=%+nBLK7Q`9II*}&rj!lq zZ%M*Pn@66*Eb>Arp|KI2ze`su<4X}C0dYrp4)B!GJ{67pY-pXY|4sJua+$=<(}2^- zo?&cfmz~N}9pYypi&N_9YBS}Y-oHtfMLOR)TYkj(-J}(RoEx1z9Fb>RYoO_6;PGqy$+VViRI_f0vz=*eI>qnj zrKijBIr$~Ht6jnjwn4~H=&(`Ze&&;LRWKhf7Y|&6ygX?IJYC7$tXYSon^Evd@VSM; zB+aCJL{0joQfouD=Lel@1jW&tRfs5Gi{C9J;jC|7xKUjXaE*0Jt zoEKemn)-mukyxRhOz)F%rt+$j@(ZQ$tB}%N#pTz+B}+2)*yL%KV;9deNpGo?xv+bs ziyvB%oKIc4C+A7HInzyU$?5HsC2nY8D9N8{Tb%2qsB89C$_NwZtutwyp`(oJ;c6RS z%P+My&{dI?4uhv|mWq@A+;=gCuXQQM9PL)bW*urFwTUxl&g|yvs&(86dsS_@xThE9 z{auWG-C_0Fm*M`}4y(`h`drG#zzHYdIT2>*y7By(_^A`bJ>g~Ck3Q9{`HNN%kCl?66^W7srD4v1eI)*W!Nd zS*h_DaU1l>;j+aWF=v>VkFks5F6Fnt$E#dQaR|=^xZeysvthhB#vR}9QeM8mrEEFH zIZhr97oMI5O%8X_MiKw9XS$TnasRe=g7RcoZl{9ybCb&UPvL0u=wlFs}sO0ou=TDY-x?5JdRyi!pA$+@-Yr#-%j; z0&xI!zjE<He$nGnCTwsi6@VW&AO4$x z=YeysNFVoM7l^j*dC+&@egyC+KPf(s85b3W)yK0PQsE4qRUFh;M`$(-GZE4hW zw|aJ6x>;e3z1ei`J_rt-ysr`VYK&o;@g&g58qiBsW28%O9h>0Oi2qu)MDoi_M^^*x z+Ypln{&Y3NJPK|NoJSQ>Th9B<8ra&=m(snx{iW-Y(wzPx--J)@KHBx`pFGl=^UE(+ zMi05#|NfO12dTj>Rc5YF;nianJ#)j2r7s;&#&#UN_UL~+ zmhap4z#U)SK7GGOZfpJZ#drUG;??(Uxnj%68M*65uekN4aev+a{js;4vnF!z9(6tK zH%#+AxTv`6&JE?S_Ki95l@a%<&t5t+@A*%Ee%37~{_KuB$6WpP1HYTQeam})csyrd z-ZyOG`PaEF+3V5?Z`?C}<*CJsdUJmj3S2N^x&NPE9=&Q6dd;aXmTG4;u+GmvzIaUN zq^n2l^Wc}cr?)*a@vFbSv|01Kf7hfBw%mW-nstBv?)7P}b=DTYJmrfu&#l+$w*R}` zcWeFAN8eEvXZK$DX6ZfK%ddWY**`9RaZ&Fh&s_EIFJE|W<@>?P?_LVet6A55)3z-g zFYCpls@|EV%w19E{^R3o#=o}k#L=EVmXACzFK_JqXRG5LFTA6t?Y6Tbs%v}KpMUqZ z@97EO>^R}l$6q>V-%Gb`zWus?JX)~mwqs5ke|yQ{%kR7ErqJD6)ibtyeCKTsTsH2_ zJC)0xy(NCwlIK78Q~$HSopQh{qt3{GRi8B0|JIp@2R0tDvUmJ-$F5vG_U{wk{_PL0 ziw?Y*xo^25=j5u3ChmIn%G`5$J|FSZ?;jcyJie{-zn zv!46;v8!Lsdve)p-I3S-{LMF?-hY1O{dW~SfBxo<_pW^5g;Oqi=J$_0^x}f1&tGr+ ztoxp4y4&u(=Cv_*9C_6ITbI5(Yy69K`?&w~uVu>oj@6^eAO5uC^_JJWulw};@a)0+ zgEi}K^F6Wm8C~~odNxux|IMDJi~GktsVo_L&!6*0?tAb7qg(Dj{O-TZ7<=EX7an{2 ztWhg(TYl{i|9EKj-?!ay-W4wuO}lx=aho3s{N{kq{U2R^<;sNnqTZ3$k8xdoo0;?CaZJ>j|In^3R^izyGx34*2uG-ss;P>0ff!UjIBccU^Sl#2@~4_?WKcV@K@q z!xh>ugEx16{oD_$eARys_VvZP4uA1b@6GpK|CcN7*>URMZ(Z{K4|kMK{rtZB&VA_azm;Be zoA;V4Z{L6P{B3t%H0B>q9n`j?`GM}2_A6Q4b=#I@zDGvx({udBS&^BC-aq#C-=9D3 z;eB2oee5qj9a(Je*CzdItTJNPSmi31?J%GFr%U<8O)lj&+^_p|th0Ufxs~JZK%cqL zt=tFGb*D>d0e%mBe5bQLuI_Xz-)}*mxyY@Y@Mo9uN8n#T#ocJf?{?BY*5g)IKkZW9 zTI^O{hIzo>5eINT;NIqZujOlSD;00Jl!0q8u6)y_Byb<7b}MJTYmHOOZgVM1ZnMUz z_aMCw&T%W{bKT1Nd2Z$Lt6j>Q!1;%`m4q$aHiUUCDcm=pJ8iyO`TL<(xEB_ z&4eskA99BK^Ib0G=KI~s-4D2xng`I2{mrF}TjVzLY=nJcOZxYf$?tsWedXeZt+W>3 zlRnOix4MmZKjc=9e%LCbcl>TgeITrX+sgY~%5g`ymA}Evzu%>F-cLG( zank+H_pgWE=d2^6x4L*8dG7(Mj)b-*y&ry1(2Rf3qS^3Z`t%k(;#Lm%iT55Xt zgPZmU##~3bmA}B;<1a4dc;I^AtG_tYJLi$~@r?hgTgiXais#|3)Oe1C+nmQRjz>Hf z!rTGOeB7n<0S`UyjOT|()5r4(;&|mTE1qw=Q{%Y+Zq-jh=4g|yhWQz==qZ=-bKv=> zobgP0(rI7vbY^||EDOCFk@TI!prh|6+0@JOEbBRa*U5%1T|Q3CA|GTwZ5TRxJvKL`%jj1KYcMfx+907>#+G} z!|${#OS+G;q#OTo zc623K(lusD7tNCHf+6T`ec4Hy4Zr8IjQ7hd>88Ar9o_sa>DscS8_1IG*ICltoh98X zS<-!Hqnq~XkFV!PyqX=|iY)02tbH{*y5DC>_fVE}Z)Hh0>NSh5@U%02szQ-1T}cuw=xyDnu7-1f>HmqNQ=j^IgiYz=xRgU$#wowu$D;fGedjykh5Ng+{&p}Mw08clAMI8?|8lG{ z|I@K%-b!byg%Vt09g4n^yV11;y%``-29AN z`QmxE@*KjI-Re?)_=j8REp;pVyoCH-g*pt}@F%zO{$|8?t6QnO&8^J5-K|^&+J|7i zc86Oz2fV&N%*tmE?h}Vu`CPUG@_OB^l-%x80z2KxzHhjdugcs?pxm7z>)AobWu+zS zNvoXigU>(Oil+57$r?+Sf40o648Xh(?ia({R_jjDo0;`+uX8K^88=SZiu>#I z^fcx57R{EE($idKqlup4te2T+YM+1{aDVbe6O_}>nc(=Iw&NO?av1FNJ#F33v!i?V z7wOaXZi5x?x0j^X@pRv+zHCZQo9>&*46oZ!ml_|={`Zy`-8YFxlENPI zME2hqX0^DL$*orXngg8QV%3+T{anfkz+I|K*#Pr>nEOn3DfPgqz%9UAz-#+r%mXX| z27w!Zhd@8rfwp&rTN&MI)!E^`uf9@l>Gy-J+1HWQ6VSFF?pE$>b?QJB>iTT~xAIG$ zTloMcwM#!id-nUd70-DgwEb}_9-1Q<0=|K+7lk1U_@B{>`UMn3!0T7e@TW&JhyUP2 z)L;0ohDm9CK9(AOV?1;C@;>M;{4Pznl{bJ{{i)$E8OR*|--B*t7yQo~6!E{aIyL;H zQ!|Hu0Os5^s9V53CnK)4sp0QCEpzx^BTT{RD3{Yk{0E$o8vc)GW)5F>HrkT2&^G`d z0aMQr;lDq}(%UWPx|P42Yw6hdb#7%o(6b&oa;~M%#COJdZe<+Y`rzM!`*(m6(A~E_ zHC>VOGp8$W1I7UG@BXD**$jNQAvOF97iA8A_{HesHoBE3HVU~Mcu8vb%YKzPeA9(! zpWy%Z3*5?HxWD645k6hJo7~3#`|@4*`wy?M^ZU;>u_j{)BTMQ*op5^xjn zIL74Tc& z2GG6+yoIn+U`~a+8-QHMbQU=X!PZKU59#qt;Kt|c|mtyZ}EQodNH1ycfG~`CGekhvrB0@$gP|S+zGq~>^&1@ z0GtAB2Hphr`v86IER-$6+;F{>hT-N`4A9}@Feg(PztwBU?cD~FmtL)Sq_{JYz00Cp4rQ#>^}|s5a+YN*MGE)wTGEg zvFA-zI`_r>Tcz@xx7z^tDlEbvR}iEYjOYKO;%im zKXWNdGqVBFej* z(fYD5uW2Iwh+Lbt)THs+q?_QJ0}g*7BV#>QPfEVax%4%zp&>SC($w+zy4fLX%XeJ)+BKLr8m4*CA5f^6^~R^^q>8es=Lv>t(8~?onAqd7Y#7 zP^=^N^RyW2fCFZVL^w*5)lx>}`odmjtnRh1Z*IVyy>#hHFtKV+bNTTTVfrlfp|T6PoWf+#mfXdCy_AMXy%n~Z z%Uhgj>|7UH?pV*ql4vR2Az6}?v)u{nT;1&SOJ3dFf^iM-rOli zW94HNZ{wm|11YpPyPC?pmet97ACJ*kabA;BvqajBHR{fIn$23`N zX}r87qs-`U#H!p%{!f}7HFbl^+wd2CgU}LVER~6tP65}Yo*0rAaoc_9YUDLB#(N7N zFRMTru0|W9%659F(FFYmWGr^SBGcDs!Br+kkG_oj7%y$V*%J?~TXa?M-i69lXF;1L zSIU}8C0m!p_{q60%@`S4b#4hHVvJdvc@Ln;wb!C2ZbnF>1u(S0p3YV?e#T4QYWpi$ zx|ZK#whBToNlp=#tZ$k0&#BqXa@ud86HU5tUOkW3(7R+mA5vlXC65E`T$BCmTvPoluGKu>ama>zDkU9-rLwB#5)rM7 z(Kq;bsgb<9WnMk9mlLCeUP%{3IMUo0w7`-~IdbP`R-e}*WiINuz5X(p8Y(Tzt(9x2 z=u<;UI_BlIIxge4_7R{fxvfjy<-ll{hwGzvw@-JvI8)*DOWm`?*lWOWv**>=RmB!|V58aCYOSf{)F1PXs@D*?XXqEyif%QNI!tD=4 zfd56_yTCIm5LI}^1s&J`^;HqX6W|4-_P&=`F%b=bkA9P z?X}lld+oK?ex1h(NN@f-VE>!1e`((r)4l>0oST}5a-H@U%Nr7;yg#eQw1ARt_T&HG z)Rh1ImGb`^?uhHJqq>7o{{Qp!Hvbl!2KG)N|Mp(2qy9f%I*(2D;iu~G(|!2qI{XYD zeufT@^9BlO^mB9&Z+rjuhx)(cY-&uTd@3^dJI*lub4b6vUGVfD!y;wZb&+xlWApiK zeIjN1pQPX3<|O`J2nvd>+mZXIlIn zRJhCT|F$i4_d(SQQVo~b>%^t&qa~>=gyBX>Y7Lu(rb02Eh&?6G9e*YzX5aOfX2ovrEGB zOJZb@#K<9ukwp??nj}1rBt{}Bz~@LoaQgRisb>P}&Wrj^E(ff5GDK+{N8kOG2e6&3 zU@14h_m}*I_x$|79I{)Oe>Q{fQ578jK{NQS z=Y!*)Z3bV{41U<>!SSmJ{?!GM^1=lizqLA29tYQZAx`n9o59bk2#(*=4F2DQ56TlI zG<;^7;jO{MbBBKmN<$dU&`Qe7CQH;~#1U|5h{j zTP_607c_%^yBYkgHNo4f??t^nRr+7fHDeE-=TzN~w zw^|(rkG>r#Ul#ZefVR^jj(?^!QV!4K_yoY+De!S8^z~Kg&-lqd zM6`RWNsgU|;*h?EDOfw?%OXTWv-0UkUM zeuFR`XciyT@)n%Y;LU*F4`I%kK;9V2M7}2>9YgIw9^L@B&4-{L2)Q3}npfcZK7|GS*MAhetp9DeyC{;qUthg90ROrz?km2E#Ncj=8SdW1W!+}r zr?jNuY3b~cc>c6p-5BVR0`49U0 z!rNZc^BF$MDChndDVIvxeevG}p-D3sxwaisj!OD$!*qOPAS)Z$%R7}@&h-0HygHLm&Jw|V#Fk@9p1yOwiaUoLN+ zXNMI~M+oMXk@A?8oUTY*cRv&dFJ0pD#<{s4%-2jzAIUhh&Jtc{fK zfUp9>VF-HY}-))r7cQnceI`Zcg9vNYjuiYKk=E0u3 z2=<&ru;(d)(Jbn$JtJ{uxG}&EzXjPY4%O^1B*`czhX>LPYon(d(hOZ8&@Jg=WcO4e z-Mpkgn$)&>nmtK@dhma?^ra5_uEy;fwF%A`QJ#;>i1d@ny8jWd09`bZItA| zvix<~c|;(eC16i`dux2M{Aj-GW0VKnZ-d{F%@;tkVzQpD+i0U~onn-|Kr=m( z)4iFgr>Oy&7GsREng@Eq`qkMkJ;e75Rd`ffle7fgwKKSl1l@Go< zjPhAJ$0(nk0Xl2aWPeg62U#n)49v1Ntz{ zH_Gn_nr8u*z)nT+q_HQPtHnzG(Ze9eLFn4uASb|e z2m~vHVGy4S*BrPO!F3yiM1Xg}wG_e`2nvKI2oVVeIR(;U;o1j6I)nufwm~R?Pz|9G zLTFEe90MT%!axWcT#`JD-EpO!B;LtnS|Z_HBm9hUsZR@&C4O%!t)Hf$z`FlgnyNwk z<|qH|7M6^6Bj6sK6f_TQ0f}it(K~_5#O8B;`r4L8Xw@>=U3DFi#&n+^<4if zotN_GGy}vr!k^I$68oHgUKW>ln8fdORPXm#F4}dN#P4HP+Zn&Ifo}^=0vpH@`S_h& zXrasacUdL=T@!?prA(l+v%L30AHh2jaDj6li(}tG>GY@j62mW%^r!feMDK{`VoG9# z$NyS~{`Xe{{Dm0!-+yxrg}<;+{`cQprT^_8G`ndnUwat{97153z@cq4IINQfw`i%s z;RKE#d0P^=6@eoOY$W_mguj{ai~@M{Iu1vZysZh`hQMtJ97FiGBmA!;{I4f)EXmuR zz#RzOk-%|;e<#AfGvRpyf#XTuE(E@jz&8=NE8*Xb@b3;hWucQEgnt6b+mpb(2;7^% zeF*=X3ID!?|1E@nBFWp2!2Jn4fWQL@|62+FL4^Nc!hZ_*d<{6_Sz!^?-nqAgKY!BdkDOdz>gAm6KRXh1l~g6tpwgi;9>$l zM&Q2@csqf25cu(1H24XE-$~#n3H%g+pC<6GPSHMiH-Voa@UsNoL-Ot=@N)!yp1}J^ zTfad3;fsXkB?9j!@XG{#g}|>8_yFO5kif4I_;mswBJdjoev`n530y*CK0@H51b&Oa z#|V6!z;6@y9Rinc;P*-1GU8{-yK3-h!sqXV{|5wrhQJ>Z zJ$yv)9}~EO$Z(dx=Lq}>fh!5me-QXn;5kJ2%+Cn_Dw6j+fj=kk7X+>*@RtPsioh2L zTtj5INZ_vt{7(Yc68IYee@ozh5m+Jq-%Hy4JJNsa2z@=N`}YL?H-Rq^xS^#s2K_*E z_#?spMBqk}_h$nC0%5s^4kAA#>D@MHo{A$6Hb@Xf9V2t1R(vj{w!z&Qk-L*QHjKS1EQM1}_mJde=K zC-4G7vyjXQ77=(cfgL1o9)Xt-ShpS^{Ff7W1%X!*col*33H%V@znZ{n$QZen!0QO? zBya(N3km!%f!7nbh`=raKSE$Pfj1D?L*R`Bew4tQNL@A)cng8I5_lVdiwXP~f&WI} z?F8OI;KvF41c7%F_(=jkMc}6iyo4J!*9m-xz;6)vO#&Y#a0#i)5dt42a=u0Aj}iDdf!`+Z zI|MEz@CgE+BxSuz;8O&CkHGH}xQy^ACwe|j;J*|20|K8Rux>p-;ExGhLCXD0>j6Ul z4}$k!52$dn>j6UZm(~M>Ubh|~_=^PpHG%(0Xle=k4Wap#;QvKnh0u5j{2igGBlvm( ze^20l6Z%U8-$3v`5d4n>{)xbig#KrO|ApW$6S#@cTp{qU1pbZCUnTh839MTW5PJGY z&#Wn&F=zUs`HSbza=a36T{M68qNxwYr%Z*Usf%Yy{Sx~oCid;uuYbS(QY)Z6(_7%K%88E{<;Nk|HW}sT;5u)wQT{iC znteujBx!RKcA&T6x~|4Xwx6uU zws1}C*MGpkTL%pua@*8t(`U?_MeS()DI>cNkm5FeYLvg)WRlzc1In#2$_WtP0q|EJ z8D-B`M)^0mcKU|P_+zb6eig#ephLfM?*YwvSsY}FJqiS(dc1BgbLfGSNED&hGO> z9wSGNvX9HQ0-R|Xk(D-XEW@W*fXmoXmi`1rJd~Z3&SrylCqK*2(S+gaQ0XbA=8>PLX-onMJ@WPaZwAJ z=A+F_AD2bwc)tDP;h*VLE|%r3Pqu2k`o)6WE%a%xFiUuxdJildXbuxJ=d(w`W zsBcS#p)|hysC_?rCMw0L?drp+ZOai_`>JufCDURbZ%G+Q-~j~gPvCx%X6tJHQGRjF z&UyJh8xr;M*^!9*Y)MV`i|ZAo*_9e+6=ofd*cs(T;y!y*)BWPA-Ko6CkIYI+2LIJx z^4XzJujzhqW{+w)+zvHbzqqhX+HPt?i#l=}Rps!3l4h$~`%xnR8?F&%`O-wc)61-V9VGn``uZoX_-vUtZcjJcdAXPb@17gXbTH?0lOG0 zgx}I^Y`p040B4R#vkH2amYHcuvX4k*u#cTY>{9Ue*`i2l9>hG(PEj%)73c34DoSeEg6=q)Nv`IIL?D0AU=L%_E?-OsCif%+DeUQX7N(h zIEk_RBkgHW$B`q(k}^1MM0zH{rHxM>k)D*9=_`jsF;1h5er$?mBFUeUmN7obo}R7d z=kaV`eu#rEb?Fe-(v#D&My6TPQ?z=Z9@0VCq%KH6P>hddBs922lVY)_flv4Gg+wg} z>I)j)r+-U^4-dA7ZRv|chp;APrBeBm?DnL))x61CjHNR}Ow{5Ttes%IAhKd#u%u+$ zEd*y7o1LNZ%pR+!&&;xCkI2%~(`MlH)5Kt9j7uBqvrm)*tuf8tKDdpto{>)NRP>c} zYMX!}G-@6#QI%C#o-f@O^Rq+FPqdpaUDZEBP<^ZXlEx;DvZVOZ!SN?$3SLZyf{yEu z<2C*9IM*GAeauCEi#;hzrNeqMM?vIQ>#w8t*OiF-BI#QH^}*10slGH_`RPfgH|VP( zuJ%*LPk;!kAfv&)Dd=Gk%)C3pr&HEPH8@+vv%aap9Iy6CtxnjLgj{N06y-25U2RuU z9`B37PDgR-blwN`dhRdj<3g{NjQ-*(alNMqGtt?M&@=0=I@>{bY<7A&lMe?mAuI2@ z9A^EtAAu7^yJcmjCP8zvx~qNJXRD$gtL@Eglh+gNQsB`}@XBmb;CwbI;%c*T9dWT( z8N45J{-O^{|IHs=6XPBR?rAi4Z6U4^e%B5p-l`cI6@Md%8~xJMYkzT#A>~I9_^(|3 z>EoKg_xTTW{`Aeo)w4LI&j36kx(a+M;KKl)CGd#^-vaQdqTFGG zPdMO*3;x3e{siD#0e+yMPZfC639}pn_=GHjZtpY?=p#V>SivV<(D#1REVl%F1mLm$ zSpt6t;IYlFX6pHjLp;zoWb$%njMvh!{c8Q_@h=kSs|0ely7uy~1XmbuyuhxKHBk-#T z-hl1y#|PzU2ly#|_ z#$P&SmcKyzX@mEOY51D}{{!HSA$TvFUe0hRHxwGIMDX87bxhPe=@&t#W(`!MBRRdq_E-Qo`TZ4$s0l{*=Hw-UWMWhiCR2UoP;Oz{d>u zNdkX{(6(vgQ3DE29F~COy z-YDp62p=2|nrwRdw@!lnfCEtc@b98sf&Ew8^#1LifDZ+Hg-!3@WZ)A9_)?qRzahQ_ z;1AjK{tfwr1Ad=P@850$`e?xKwCVj@8<0N=^tQoI&f9_Bi2m88_YYVvGvMd?(Ifv5 zu)|3HruwH=gW7D@g(uV^+&Zcii#76+$Xw$a~;v)fn z)f(8oCcrBKzh{C*Zw7p&!0#h?Cbz)X3O?v>Q7?zATEBZ0{6h}5JMy)1y(xnJN5JEF zu+7Tbu|eQhq8?B#fxk-d=%*Hlaw8^a`U!{Y48h+xL2DNr*R28{Bk;*!|1IG<%*w~3 zIDyXsJf4^J5&Zj1(ApEv&*B6=QQ$8FJ>Ju86#NHH(ApQ>+tqP_ezGlu`f-8%0=kh@ zGmiV=VWeD~I8=_~<)#q40sWYuPZjuCAWsk+TiX>&EK)HTvhafKME&@7IXOc-OJS&cv1VAHYYb36N4L z=9i&kiQWNUE#`Sm8QcyzwLz*C^V<51K>kQq8w8L2x|-nCKa`^)2p;=&X@(}J$_M9} zhl0>!f8P^CPMl|M%h2?WDfNIyKTs5e56&}J1;L{L3o`V2YsC39;Aa576~SM{c{AWA z61+j+v0Sk@SBNfR72L zXTV1QzNLu!^b9~#dSE+70#L8Rhe$CXj}h=S>3TiH10D^o!VjMSc=UUv>AZbZd?Mh{ zza1cWgTP})-xCCnes3G#yAeJ^P;Y=QAb5koqu+A?zP%66|Ikm)0Q_~5{tx}(#PlF~ z1AHprBSqY&H^2`GrZ>PR_~~sp>J9L*etJj;yb16Te)ufFn*rZ6Mz06NM*+TmOc1*T zOf}#K5k8Yp|A0S3@CJcLKYUE^nfwm-BP<>8`-9-o5AO+5E;^2FgkHs?AKsv&H%K#3 z9-NPj(c8%yvK_c!CbS2@TZ7;i@TF)EI8Pp}mlN?gPu>prA%wmh@VIU*B6x$qx50K99oWA3 z9?`i$@G*d&B=8;H;d-tBKJ5UX4)~rvN`q7d`0D^ajNlCdkMAn&Gg{v+HGq!=d|VKG zd%zom$kPGvSJNne{?`%k^=VWd{uc-MnzTSZod91M1m79kB?$foz#j{Oj|cqzG}>PL zuM6OJrUly1jo2=LkMX0w3Gj}zKtJCV@H2wYcLRKukf$H%kKF;Ek{0OqdH_CA(5Djm z1i*LI)yp6)1O4{|d`udjFVH^&Ospf)0>|+Xz+X)b^ust2Z%7T4Clv6tse$?o1AJ9# zpdW4l_%o@2{v;gmrKy4bBm(dyseyi@CE)i5!M6hZuGBz(5()Tise%5)2>7DZK!0Ka z{Hjz#fIl$<-jNz;4^e>6Ne%QT(SVi{1Uq`j_3dq@rR53y(uqXPXyd$fm9f&QTb+QX)eZ3JLFDfa_~AkDJpey2h#nFE-!%w*Pr%0p!S@2Zaa5pR?G1QoRG?q& zgY7sn&>n6Ee9g$f{@54r6(gxW4Uz)*Td=)GQvDmG2EZp`dyS;}G)PT=?}zO*Qg3h4 zc!S&@+bf7X0|37P@HY}Z5kNl>@N0t5-wJp~5d0u)$B}{dFc|QYMh4o?5WrhU()9)Z zyA9h>$KN1DgFLqbJ~2qSL$Mu$;D=#52EpHf?HB})^T0)m_2+oEq|cf6K-#=n`2C|r z(=p7F=I1%sJE`j0o7laucwg_^XHD|Q7ftf=uT656*Cgj%G0DGtZ<5EIGs)8+toXtt zXLdHpHv!E(pPJ+_2zc*nE5J>@V3I>>OmaC~J3{={uS`s~wM|CGTd|qhJ7Q;=OmYR_ z3^$o%`xT?S?5a^d_^VNFGMMBqZ*J)eAEcS&H$qMF*Fe*HfJv?cc+2NJ)MtXdg>f9x z-kEBWXF>elktW#$yxad`l#_dz^M|jeNaHeiy>0*O_D) z%6CK94q?ZgCV3L@cn0JugnW`2$^-ZTkRb!&e+)Ls+rmxqJfImbo8-gcCg1(PPeXbo zgbw{o@(2jWu-yJ8*$MFU6q9^8*(7h=VU{CDnB+SltcDN<_$_eV3!yi_bwESgF7ogF z49rJIiy&#|jq(~T?tj&_|GcRW&IFt2vlMgzVIPE#Ap8Jf;4+h(24Ob9G0XI2tMFItLdj!q}vpYWsdK_sLZI^VMh@gr^-(Yts20`Wk?4DmoheE+_Q ziKbQ^Mvn@l&Bz=XKbR+{;9)+#zf^ti+&@>F-ZaVe*@oS5qpFxO% zv@8htZE)-tAKu@R!5EMpznOk6w57bTNY8W37M`y1YXG?IW|KS!g0pWcc?Vo4K{yGa z8bTP*FNbSixZ*wX|AL^7)1~|}^06Hz8N;3Hpl>~FlDEEKk`L`P$)h3uEWqtwG|9K` z0(s#Y`J_p%dEO+u03Q!DyLa$Djs5aCz@I9+a5~{U)pD?`QJxvEqAm(^ zja%n#e=Ygb({Ft-{K~QY|D0RZKX1|n%g3fqtM9(!>`VI-&v(CF`pUM(_F4ILQ!Czi zqw!Fen@+txen;`qkE8Y;FL|mYBq5?GZ1QX8jqi8$Mjl+hYW^*)({m=i)M@I8J8qu! z=BA|TB`p?yVK^3lZhNoje_V1E9$a|C8*jGQTl>z_11d|DXHJJN8+b*E+PJUfW3k)K z7vD1FuD2P6JAcgAMJr0L%_+8%gd+SIvmRf#hT$4b+F{Jyxw+?9I`9ZxhytebEu z>gV^*ADC(N9&Ynp$=mK#MMth)==9~Zw3|O~_tUCRHq1<~{B7dY*D^k`y>YukI`-_> ziEmXV?Y%Jiv*M~d9z1n+&u@*Nev<2*Gvey`c>_ll&3?I}WXk7@Zw^iQrjtBia(b&5 zPp>k4Ic#B=^~I!+9?{W}Z$BJwJl*Y$oC&WN&W~?dIqS&NwNpPbU-|0(?WfQ8ym5QQ zfkXQ~E4%)V*Y93yI@EXQq~nKQo_n-3-dXbfo3Fp~xbf>Z<;Tw*blf)TAK$&Y^xTu} zx_=Ssysmn2o5<<^EEqat+nu=&n)cn3yCU*qbM2GYT5j#}iqz`hQ{nk3TcaAzJsYt; z=SM^5KTfuobKit%mp_<2bIrm*bKC!`#RKz}bgcZNruQeVdsciNeP;BRv*%wpa^=dU zw>OS>`|$Pu*mz)y^6aOdKD71h?o%hLhS-0+Fz$!hZ=Ibz;n;Iuws_;NF@s)9{k*rS zD!pT?SAQ8T51O(fH0j+-Q!Zp*n7!}P#(DjgzddKqqoI^U<$D_`Av z;N*-ay8k%6e&@5fd9AiS81h1kmOJknWUecm9logT1SxFY=y!@^R+N1GO7DX!hje_? z_{7F@TTE~N4Eu6 zM;(s+_MV8M1-Vhz{ywzDtVxlE*4Lhz`RJTirZs(X?SZM5kLO;u?CVy${(a8$S(Y<& z?8(>V+opD({ru(Yrc`8%nv?d$(s_4|&OQ4|^*x`SpA~swc*D@D!I`fdd*QvO-ui0w z$FGg@UV9@k?#JWDA31sS?}=Mq&wTFLLtVoLRUF;g;bqjr>m{S7 zo(k!hbKkb!^Lq_`JMz%(jmCF7UI@F#b1CFz{B9io#@>UHoxRV|!F&Q8r%I9~xdy_- zU^qSpf682{1mK5_6|V|INn> zOvCryPKU4;g8v+F+TCWkR};U|IpF0QJ_kg9je*Kiv!wJuzhCYjxx?a#xa$w^{Vx`G zzU(bdvmCy8SL4O^mK^QYYSP}2toA8R)2756*T%NzZg}m9F*j6?+$ir~`F)SXLp{1J z?$HH*P%ksstM8@wg!zkR%$YZJF4RsWNvf=)L(TH!c(eR9#6O&4mOuN=BtHq)b`O~4 zK|Rd!Bcsgn^=-^@UkHmKZ3^E1(xd6^-Kh8GGwV7I=??&GO z?SbvsVxl>Kc2kyFJ__k8$D8H3aD5TNdcd{1Kadtf4WvH-w5#EYe18Pm$|+_>hxG3g z`WE+?;k%x8FW2ZywG~XWZQ4ZkAA}}-wSXqgryK(g>>2ubD?oALtgvL+0doOPo0}L)3R)WBtd+{ zqM1`2GsnzajtGdS%$z%u#UWWD^ccnXxCJxku~eFuC6Yh8b%Z@@VBZ;Y=W4i8ei^B* z(bf2E27O%ei~G;bLPJAz@%R;B(`%va;kqOrZ1^GQ1Ix_vw*bEap%LOkmYd~Ifd+_m-9?s$5lXdfjJE zk9=a-gc(Cia?D3Rd_M2go5A;OG0Tqw{2+vJ5TYTi1B3w(=0aG7xNT;6I9zKUHv7Kyum{!+TOd7u zt65$LR|V2PcWJc!cAMq15T1Dk{3+nAE{%3Sz;|!ZXj9zaS0O$Lt~2(54|Vf!5W-s! z-gEPEKZfg<5ORR_celnb(xd11`J-m}NeF}1ndO^bhWc!RF%95!r&)GE{H|Bb^0N>! zU*P;^J*?+LX#6gLo;GaJ^wnjHMtcGH+^|if#s1I^(q=siJ{EAEtr~3@_?Pj; zX1OQOJoz-|yR2B_D+8>qxn=@93WB;OGeMpXkLmMLnaW7s8}E#@Na|`h3w4 z?*U={Q+m3MPY0Lr4~P$aT9fgP=go3nA=o$IK8CRRX}z2`?hY*PiCr)*?$YZ7op7r3 z-~Z*fqU44GgFFymduB@JPy2T7Sh;?0`rF@KI6V00zHj1iFk{;6oSAbM^u@Wz|B1iZ zZ?upaPqmPmzA{S#E|{fl5ULW3ecYCasKXJ?D-n*6x*GL+npR?Rjy1Amx8n7{Bp15K>Nuvc4H;1YwHW(vKy^yz^2!j?QJ41H9m?xRZ(08~=`F9q@h^%30sf z7;S^%!y0h|-kq_{=FZ;c4sjQiK+bDt39tQrypkEO{obd57bt4&N#tNx9{4pxDlB!} zfK|$faBoJeYg0pOR>`t8jjg#|AcvaMSo$U)TYI7&@KE$7sK+L#$L2m@GPSD`x{zWk8BGSHgd8%Lb_L26t}&| zQBqzCQjKC6iaZ$=He?seG8x?2MIc=fYB|;?T3%aceucEe#43k3p&MA`jwu7U46-Mq zR_Vdv&@xMvF!PKm=Lv%ge)FqBqC7iswyc4CYp{y3S{2(diK9U6WosjZ#C7d+CFJuZWXxsq ze*%y<3zW?hPWcj!mT_Tk#3Bn^w@^8v8^D@kA zsjwp3*Wc$Ndk|@J7vlvgn;NUtR8@6$MA|W=j?GCPK|G2{q@i z!W}~L+f~V-QQTRcau6JotZolpKzHky{66)K!%W>6iv^4Y8p$!`r}w!0#S3`l7x2nc zQ&AOLZ!+V2$Oaay96ykGBSOl3i`j$+}*W-IhaErST>ccu}LvqB!#vDQ`@fWfv`L z3@Pg_Qq}-cRu6qyv8=3JbxYkD)i&i7#y`|$sX%o&cyq=Hb+|3nR^=^DQD)g`AO)X$ zPb>KS_q2kKzNZ!Z%6qzkpMDQH?sR7~&Tz382i+YoEU5k)#$MHbJL^+}IBz9PdTU@}QxdD+DVL=h#RXlsGGHXC zm-4#gMkoc_kg(Dxe68~JDI~A--fNJUan>ut5d+tvcR|XW?MEazC-p5!R+6TnX|RFA z5$3IvIMupS$gvdE3tp=f{6H!CfoL>jm9$ilPGF?R07Q4$^IbL)90PZA40~Wa_CPg@ zhi5^$E-Y6G%KFPmHVTzMNhQ8fh-V3@yN~&Ycaivz+hPRPVAt7)=pdt#_D9mwjP!sz zI~v#>0P+La3HyjnsFH$48w^|+SH>B4_8C_;H>fD+gc%jeKPBX{AL;gU%{RC#h z-bG}&pK%!d26@#!wrTcZ3$PAXMuR(}K^cCM4Ac#%qP{1&ow8_za>Ge=T!N@kiRMw6 zMWYo1kA|{njPm0NpDlyzdNJSC%V%@JJSpR%wBJr3*Wi^?<#X1@mRXvx1CognP7$TN zRwei(f_J$ACn0DsF;-Y>NA4PHP}&;V4u-wpN)05A;mq6qTX$Z z1yhT$As40l4)_6awkfp@I1S3<-YrIWH}A*rqj)!=c#a$0mPV^`wGoFJkS=EuI$)e|hFX*YBP*JxcC|FPhG42}5IuQurtgRWay>8c$q|SbGtZ zY|8vc(cT)-wqhmPUin5TFAU_VGs9Fn)B#{b9gHr<`%Xp#>t86j^4cXfaSUgRg}Nx5 zqpOjS0i}UCN&dC<s%&^?De z2Y!ZGM{cO6xD*MPKwED?wR9B(4Zj0{rx^3tmB%K_kRN$jeJRMn?kU9l)|>;-m`u$c zPt_GjR)+RQW^p;z5H`*iPx%S?eA|U--cyKCtDwEsE)f{daM~vjSRV7Ld0jexQH991( ztCJ;$IvM*=$b;?Om#oT{qRBU$P;vQExO}NXzTv8T!~EqN#^f8upJWEfw!6#;9G{Tfq9TozoN|(yG+lX23oc=6zoBSqvu-xhC`!&CN>I z@gK&M>e{HZ1DKb9Rp@=VRMC8sC=3_B%7tH{hK0v2V-4|F%1ad4c^5}3p2-=zJ(b+H zu115KVR^hyqnO+h-OSpo*V+vP(<>~EDtzpBR3XVDx{jw1s|8xa7-$V+fJEg15|wAm zS>RKisLP#fcGOkXQ-YHzud}GTzdL%JQ5%`XgL@nBp|Z7en1oIyCeQ_l{$Hx=|LSb5 zun6QqXx46PtR&BJv3`~l!TX?R+E1wYX`NYdWrh2%@Yh?GS!&Umm@~f<<6ngHM1PwyiZOT05rqk(Vm?9H+k=URt~Zvsew4uD!9*L*?Uc`(&Z6sD6dODrnN0gL?@;8_>%%#W5F9l%oEAvmgz4#mk)as-ZYV_@Y>qv)FL3$`Y;C8tjfu5_W(! zdAEhCo}PKOD7Ob;+%(|8ar~8|oKHZOT!ZLsSP45eP->`6d1kCu7fud?x$`($IeNlr zkYm8PSuR#fpTUGO&&7<3Z$8A@J(hax?%YXk=RQDamTRErcu;O(0i>)wj=u^scix{+ zc<+;%1P)mJ#__Q^%zHs%J)~?MmW)-Wh7UvX6;>o`eaNLY5+Aed%9di`ZMTyO-r8If zR9^P)C9S-PFfH)*h99sCq%1t=7~Om$F8VoGBN{L38nKo43$Q=$r}&fh2l&|8=tosI zA;n8kg|AD(FQlTfqY7|_%{C%a`xl;$!gZje_66Fkxh*_}8-(F8r_tD*J5|*x7jPH6 zfw|xWUuO|Bjkj(@>e%M1x3$q66MBhC7@-#e$jCwc_wqTz_~{m?DZ1Vb3XNdqUiuj5yDhBr1b@pwFN) zfIidLnO`gACFF#PDTl{{2{v_RfkInNxLlAt2B|Jq;CRywv7tod!Qd{J^=$L+Lf znYd@t;LLA;RR&O0AVqe)oiCzlZOZr2VjB$Bc1@hie#XAuuGF!#P#p50A!3}jOL?Jn z^Xnc2Y245`4K^jLuL0Mit`IOU=MYS`){O;vcWYO+;sM72^155I!KL1+yv+DTt7V1O z-Bi~FiL;fVtsS9t?dsYxvS)d*d`)yCu1S?mLJ}Nqt;&U)4Voebl%nFIo7vB(qWfLT z0#^K<3`JRZ(6^o8$*57L9Tcm2O9T$=d=IG8YitW2$$vb+wv9I7Es28;9IEs$}geiuRo|Oe;F&k#Cte|*EIDY-~MO& z1w~M&BHzxLkKZB6Z?K+U0^@hcJ39ntkqw6YUg9LiSARWy(*dME;2kW=FFzoT0Zzdn z?8z=?X3}8QP5@HlbamTLdB1c($9pH^z2EzV0c9ySEbb+aQdIhtdiuGHexLUxMjs1) z?ucmr{-}FTMycX`mGAbjJ?%l-RV`y9|%$Lm?QW~}#kt>_Jb^x~`R%mU{aAmW-n+bwgnT#RGRkervR?Ym2rAe~Rj^FYYYyYJ)4NYp z{I*xMgN{=+-qk$7*9|Sh+QoxuHh%2k*E&N*&$RR+J+sWRofd!P6Pz z#ce5f;jWr1W1C9-fu8ypqu%DXi>WP?gujd~vo!IdQA0THfZ(2tCRG^H&%g4bY99L{g$*=knl9}wQM)3&(E8?oFXjK>=j4TbVbp>H;uHepYa&2A^rd51H z*q_z4S$Q_-sBAwkYx#KB9A^7)HoSW=V^Ui1x1&XO~!l61{+3tzzk?8>g<{YFu? zzC`*>jZ*Lu*1F2O%D`*SRO!lKy*BR_z9LR#M=~k{yPm-a#-P$W6d6E17!0Fd!VG6H z^_v&iV0Z?c#2MdU#8#+|FmIKpNzIE$U(Wp33+nM{ICm@M^x#y@__V0=^DN^jT$#C< zOFHG-@a3c-bxUEQ;>vEwW%S`M@&f0xe5Hs=@f8@RoeudzIe_fgc0e zj`_CGRl1g7RkEd?ZM1_`HMp4e*^x_ys=qcb>hveShy)dXb~Z=tyS$V4cC+ zhj*Q*!^!=Du&3A&M)o#!sm52!e6Q%9_H1QVH<(SyizY(#U{)@&6=OELE}JDH3~8)N z7oIWdFyjqtB27?B)p-5vy#JHEl0e+7Uz z&94yJaWlwOSj979lej$?ab>U>ab8qeVKqc$+%Nh<*8B#l43|y~%Aw~acD?$X{w(qh z3(TuoX6Ny0CQ6uhhm5(Dq%pGE4y=DUB3K^*J6{G6E)>Gn2-MmWn-S_ zuUv!j`)FBG84Dq?Lf%2L5DfcatdMQZ^Ehyy`JEj!VZt~R*3B?5YO@5Gam0hg`$_z- z5J_b=lrbr1Oz>pW?oNt^%xpiz&DP#(-_!AE%VhuRi)+`o33)Y+-sh0xDOIc(rDQMa zF!d;I%%0-1o#L{E1d5i<7)3ab#N#8hdG|9@uEtxHammT}6|n+JQDfY<)01veCuJP1ao`aRnUU3OFDXkPxVV zEgHLT_aM9dTsn3IN%jj#qWvWask=wydxhoO$MbpiafR#?3W@bsNC+$v(F)6dVQpnq zF8$1`*rtp;FYK}|OC=tl*c{9c_Hq{^#;#1QLb0G%Vqb(lj^0sh`3*YFHUn_>t9-{6 z>k(yZnLlN|mpb)~dRWGvYZ2DWltP_P;E|yt78ZR2PJ_&Ha)jG%YzyOAgDbnS&Mbz1 zF?(g>N)t|4GOoG-$Y!V8e{w$PtdAW(;lD0{IsUjia3IMW4)Yr4MVM}0b$$)g1;v$J z@3ttBmU>5bcV3h8+pF$;6vJWx|__8DwUUZ`{qYw!`Y)uxI>>epscX*63@p6=t^bb zGui;nSxtTh#|otLUN&Q56`LEP5m;T><+&4?f3Yezgz-@otiXV8Kxe~6xht9Vw`?PB z|0l(Rx?Q%e9!ojj`@nrS_h=*9Y(xXvEdEM)E!DiSY@aigueaE-w-u)xl-L24Xz;7V z{@wnSczicj0_nW{p%Q)qboCdY2dt9iyw)g2a)PrQ8XSaAr~?BnZ<*H$XV%FHxErVE z^9a6Qtl7GRGL@yeic2ryt|k6Dl`t0vj^pojQR|07F9Wv>k*GH}pLyFLU+Y?Y04{z4 zC-{|uN~rf!!t=ZQl~BA3m4I~Kn{nZlUG6GA#)LV>gfX}{a2$VIM6K_Gql^b5*SdOY zK?<%9lQf*QKWN0mrm4~3>+rUVq(pRDeqt$pVnqjt^~cjF7SeeiW2>|B9gO=Bmu;B$ z5NcUp%0RUgH(P%j?aHy=nD^mXKuA|{39APYp9MMXL(*_zAq=9PvG|}Q|e@!$#g_=M* z?}o^LdJp&2Tc@EdqOW1YtZAlUQiC*1jh{G6pYj)HCKCtgyuY_X&gJa(Xjf{Y%Q_JI zc@le>LRr!K#6@MEz z#B6~5dJg>u8~B~wKwM4?U=wcE`T3f>cu+kXIb6w!uF(T|ZP%X0BQtIZ&Gl1vJ9Z%P zHJ0j#4|AyJm8ixIP_WK$JCPzzUady%T-!S3m;bCiMpFl%sm&`chN*&_P zu5ek0VZnv_7(4b`%zl%GL?#c*Yp0#N(e}poA^b;^nt9n@@;yv)_Uqa6=O*ROsB(F# zfJSY>>!0v%!LTQ=1(C-4WVmnWeszbsD3^#eid_I*d$bWbzJDC1&Tp2&v@Og#Fhm`j z&wkCejKMQyS(SBQ;Cyg)p2&g)9v=E;SBw1jJ&qH~T_6XVFUs0`2fvTmgGiWN;zi6Z z3rnLm;7JPZBS#hDF)wE5z*y`=7TMJ>14amDvv|QR1>8mTcR^v^mn7kMv)tJYz0aQg zmD!iI_upNftB}#LBp0UswZQEv%wzUg?MU!Cb}%OV_pI?+hLGR&A)Q<|Av)AIxoKe z*n0wdR3R4{Z&@&^K4f1A8+e^7Qd>Fth~`@Z%Y*pb;k=TzYwcp&NV4-(1a!?-xh7@L zEZjt^;)8+n>j=l-90jYuxLdEai{sSlk!1TLlUYkP%yP9VVPFP;Ng;Kod7YvThd7)1 z=4qZhLK2>wJ3Z&ckf?%Fk|w1|=sK$K6~r=Ijz;w_h{arofICAJV|_3~@SOAR5c*Dtq9OK!*&y~>_* z7Cm605i=;ASR+Q)wH$C71VCIJQmST#PQoVgDL=^EBe1eug$~xS@Yi`F#N}DQ>gKql z-jXnnRmLGIGfz~8(f4M=XRo+CIY@LIe8NNoiz z-Id`(p`{0_t&?oDQv407>D$b9iuZMQrXW}03|561Y89riD$MXz;eJ+y8KMgJt5ul6 zsxU=VVd5p`uiS+QxRTSg-oPzW>3ws!Y8H9@@z}Jm{F3Hq9@ysJEAHNgy#Q&vKQNzv zjE>AH{zH=)H;B=<#CeO6+|vX(m9AU)p`nPrw}m}0;NueS&m~C^9@~neOV%YEppLR3OM<3ZL-0LY)>%6W0wVsY-g-D~@%_tf0p%VH_ zsKn3K-Pe{JGRU*uG{|iZ8suN#y7Uc$T>iR2zU_!XmJA_si_jK+e_@-VUNgwsfqpk! z4+HHYaqS18x&450dOp%8;CzHF!=tC8kEwNKEAEWi$P6W~i;_Q$?di16iEYpPrCnKh zm~CtiC}rocZgwj|E#GNv*vY!5Yi*Tq97maPvU?wH5=);VL^+S(X^E6)%7?Iw$#uw zlmzX3qoe3IzVn0z<@L=dU{zhdVCQ7)%2_Nz$=l2huN#!Po0;LMM=Z91zGI9$U|Q+N z^nS*)vM#~H&fgiU+y4jwk_v;Kav-DpkH;C>^P;pp69U?k-TmHz-A9kwU&gd=^l6qo zHiX*Gm;&0r2N%j9L+PWMPP2_LCihOp+cGo6cpHYCnZ!Y(hb*z5kN<{Ot&9hNyy#5-|X02{RAJDs=ywnE^b47}Q?myCK>wD$sT{eyZ8L5eu#Hp8IdxE^(u-?Yb~wDuT3K z_(suoe{dly(7=3c$Ind^zYpG(XJy zF0+JaKBwz>v=@tBg$mDd#U$ar?MZ_x`zkJQar1YUD|9qIvLmuMuk>=nHkSvM*6IW7 zV0<`+!~8qj==?6^w(P6(M*EOkvp6x2G+aL4 z@$}{M&J!)cbNlu(hJ%T8En{;wT_Y+=?+uWbC3s&DcNVaAba~?0Fdff^>0UW^LNh8G z@5Rv_M{dHw>qZWU^v*^O#h69Cr;i&?59lg(mN!(N_hptBk>1|y9*0^m92=%Mn^+%b zRm+CCY6wi@TB=V9w_$Tom=*A)TiKBic4U2*TVl6RKaMLMPc%*o@cw>&gOQ@dyHSE# zHaDq;xk)Xbo79TAN%Xa|&iqQYu96za(t|US-8!{3K7xWHop%v#2jy2A@?r>iC8T@X zgo^Y3N3dYrofD}`T&$nfKtHQOm+q`to4$3fK6-A$XPvIYZ1Xte3HuwasF$N)Y&l8$*Llq5jPt$A3-_3Xnst|uYt9siq9Oc#C%q#GL*<*A1yaqLrfgLWQ62=W;LCg@f< z6|lMcX=p~ns!VrwgPh%T_E%SSBR+YW5#fnB zVfWxeS<|3OYzKu&ksk>aa(ZFRY^sYx#6ywp>_#?9H`GOntf41BkiEJarPcAXl+Ndd z1-U=EUa=MU21{H*CKvG55>Ega@cH4(RnF3uZ1UaJd9jrv+BfH6mBV9`7*}>RObghZ zQ$Q2JM_X5hf+aldWNsbj=hbWz)SaDxE9L}kSD3xqg53pt#-RFh5N2-yY36$6u>w@( z8E-w%)V1Q9n?E{vHSQ^p*zH~HJsg!vZzuQF+VlUcKd@q=Hau)VZ&Cp+8gHC~IVKhg z3p+bI-zz|I*$wo@wI|RK*pxmOnP&~Ddj#h}M~8#wXpz??Cl$RbPJmMfvs+V)Yfqw= zwJUEn@ZD-lS7%Kt$8F5E+o7dx#;ilLqjArqhMPtVF9>rfwCV?b{Id(Z54j(Jj`g{x`_7;RwrE zT{i+F8`d&~$Ae9UW5!dYceaP2DUpYbb)o%^) z57o+zYt)%zm2%x0F??jyDy`ONBh(+O85|n0HXK`KsSu{Y2;UoVGBf7&w+#y;@tmsD6X)6;YYQr5kZOyL) zhd3ZaeH+pChd87t8yU+g<(G$$Ik;F<==L?n6Nxo+D|4R2m(1*e9D7ixRaB^_1@({lNWF`#i?KWIf*iZh)N-gK z3kCHlM!l0sf*p7#+mRM+CKzQEy<9;85aw$Ji7qi5sZv!n_5)qaQy- zZMlAxX3I6JG+VA*rP*@%D!u<(#m0r;8z8E`T1Nd<;QNh`&)Stbf3;|(R{AUshXnYg zL7HD;gf|m0yXeJivx@tl>JTwR8XQqD3gAa4*aS$yoAB^ZSyG2^?xc>c6n&>bd2|IE zmDOHD9`WK%>cUEOm>8rvDJEC(N=+`;N}XIQR&r;Qf^y-sBf>ES@yRP$VO?!}PC$q4 zI5DC`*p)N*RIsJoSASAY7kxQxR&tkv3n`3$y@Gdbpgg>s4O+O{t=PcvWgmb-4$vn6 z_@>?<%~)7z@2t>Ddwqqjv^^`BQF!MWcxyUXY5P5vN-O5HEElu9{pc2avpiNz)P@Ly z>eT*_5Q+h2Ym?S>RxiUw zufo)eSeZ1M8|`)DL><5BYZ4+K7*F>z8%A!m57PVj*Tj~)xddX#IUokSbp{;TIQQ2 zY@qd6YFT%DGmohkXRNq~w-1M2Y@uP=!#IPq#Q~G%-6fhdhnMK2*|&uE{fEVjq)J(` zgz-0$4ykPU1Qz{#a;&bQR^K42{nJ2-nn;RD*B5oi65c;MGN;j4Z=3vIV2j>{R$*E5*B~&f@^RzN{<>|`U%*rV7&NuiT z)2EAc_N;LRD|8ofx{(!{QAwQ3E}XW|>6%Z5LsVZ0M20xM3??SSA@-6!b>2D0!TbAJ z2b=QncX(DQ&ny;my`4Dy@y+#Ek*o4?5uUe{JLK(-z}7uEo!r?Dl>0#4AaCk5^ojdveTR^Ief0S{v3&cR_lZ7#sP+G~^{1kO zKi`FgeX+>r1)TX^rM#|Xg~J>C_O%+6y`VfdOYlx*gISE^=qzqDNoinrro`Bk3%g-? zS&VU4b`0|!Bi)t+GP+Pd2jkbrNLe_nfgCwBD7Uks5b6B|gz$bX@eNnUSj}Im%TZi{ z;;scw#*Lh3-4*0HM9=fvMaUD8-e-^}JEF@-a9#|>Es6wt@Erxg@dfr)sDXNp+Zabg z)@9ZuH!qp+?|4ICPe9-p~{IGzG zf4(O)`2%VJ{&=}rZS`NE)0Vs-P+K>Ah}vTBh88NRCJcU<&o$QG z|5RU5KAr#9w59253e{KO{W7?`+B}cUC+d}T^SDO~&|NQ4SMK8Km9+Upwp!(OCR>fS zyTPZ&@cCG`GniWapihryKpkiN=3Tvn;i$a7pQq#f)jXyW@85;UugpWnxtF?wdh z7_-W{-Z`5>B}qAc2MSoB5_i@UM=|1xKWj#{{hrd=uVfW_{^@M+^K13NEp{Bn5$upx zJrA0zHL?d!7nR57sv}pevT?3DZ;X@jQq^NJ^?@ptYT|=Jmz+V`gIc9{A%h>3)KllC zR@&sk(Gpr0CPorI0guZ*iH|@YJaK2!3gx~h*h?>4LL)oNBV0IBHo7-6>&xc5Z^^pT zV0rpKY%UIFjhCa+Ze5r-N1_nPR`@_ zD>;&N$Hh#7k$MRR2T0J3Nx)8zzio+$c=90mZpa_bjtKb z6bpJXmlZD)@0-#UkGFDBhH{|~&m7k4 zt8JcQ)Q25LG?s=>By*|MXZZaEYw#1ynX41bk?SwmG$t53ro1VF>*E$C%PA&Hm5rZG z+r>?i;*|jY#n$^3Yt$F}`yBsb>*h$}$kMw%T-C=&K=NDg@D7azyOMVk_M7}<-9u)q zfS2az3fLJ?z$2^x_RQHByy?TzaH2-GDw(xdH+GK--hh3RxKqW^0et$2i?S_OoPPg* zyuA;6l*P3-{_LN?0t>r=M59EE5+Rm=(F6qp8X~I^S>0V(z=DDmb&K?s!meOTDq*wA z@~~}aNvkdG#VcC8m$#SpQb7wgP}+c{_ePqwX>WQPZQA>+o7<)}y+(}WJ>N6)Jo`MG z1?}hky+1ym4fD*OGiT1soH=vm%$bmO{TV)@%8bL&>s=leT_q|N1Dv9^$#Eg~a8qfV|x$=A!D?lBw)9D7FJZ z0Cpg+*@PVkgNi(AtjW3pD{)d9fIwT_&KH!}07Ty#Cr#Ijge~?<_~tuIx`#W&u!lR5 zi9OuyGvyK3PV|$HGC0Yj25m1piX;Z(9JjtMwM22`9t#_Sb_hHcz&h^=h zbHal35jhv52JEnx6^v z6Sl2#@_G{O=E<;P%}C|JrsHxpY#4@)$lbmbBMqARcD^>1Gd1`w6W?wUQ{!nK^gB&c z<7s_rY|l=OW>YRPHMWbXu~SZsW_@aG&7B(Jp2}998e4d3Y>`vr_<3oKl(i`MC$~fN z^o!>)D8)?a$(bp!hb%MYk%w|;%94jLQ}{w`u~h7_2|-Y8!O#u~M__DPrp@^+i_Zn= zYQ8!Kbs$Y2xXj$lZRWqy90AiuL`#bVOdp=$ytOxL)2^z|&I@~{ApHyEl55f*ek-}a zt(NKyw#UmgA^MM#POJCE zto;ycNL+mIGYIi`Fu?952HCH_TZvu)rHk;6Gn7?J{3je*PRbMtUB!@y9Po2iIGP5*%VRI#U&3R^|ueO;B$yjIAm2};>4~~o4Fb%cBc}j*@8)qT88`kRTk_z zR{^^-={QxQpUfXTW9RywU8V3z8ViUA3EP9x{8oqcHOi3o4GW&$r9~dlj|o3vS}>+a zb-$_7Rb1(*^aPu(NT0cCq*mk3qZm$}#ExwDNO&i6;CUF{$@J@r4(~G$7+rYw0fkTK zWEZ}0Ke}+N=)wb3=K*UM#-<1e-*{joMu&d@PFJKvYgr#~g&bbIVq=80@G9)zmkjUE zj8%QT&n0~b!+j}5(jeTQ3^=n&nl@7t76aiChDF(_XZUmLHO-HjeD{?MB@1m15rxIs z(|ngf>WTLoV;{E@d~UwY;^o^c-TM3z`j)TV&sv96xR=L8WThDWY&6$Fgz3O|m}eZ< zdlJ8tBlUs%g`x%$WmZ2!vZTlsXSB3Yu||xd2UqGmwM)C^eyND*)XuHQqlgiE_t~7j zl5b61tB=}qr^Tp!dnG`e6wYAHPTcfS`xa$LZyZKf60B*2NI|R&CHHg5HsP+eEg*fj zRoSt3Fm=`QD?#VJi$8Fq_t%5HCjI+9r%C_bY4$Y(cTuAMh;jEqh-mo$>*WfguMqbv z;$WW-a-lbSw1wi!j<0U*M)Bo9X1I*ft`QMV)!(alEi7$(>$`C^e40R{PvUCdfxn`rJfU?%&q6(Cs7X| zrtcOW>-c&tU(QRQWd-Z+#%3qfE^I7Qh*P=caM9Bgp;UP3*|iPM?pdD2xpTP%=N~W6#ra>C17|=?2Vqtx@-;38&TD|PuPXpRcP$fph7=-+wD>RU z-yv~~SAUwXTyQlCvd1-Q2|h^1#eatO%iN%X^j3&6!cUtRbv(A3PJAwaRSD7{h8;V0 z3uycLM=4?mdJgYGj>K6K(&yU^dLLf~6jlNSBF0yiDhfB?pU?o==x;6K9#| z2wEO*Js-MqQ#RcQlMHk&sEt{K8+T5H!e3APRRk(wW zlMa&QJJoPWGTbFkdPvBkmD8|v>$CHJ{pt09AN3zR+?WEKV3L9wYG!OHReZDQXCU=8@IL?5@T zO*)+dAq$-rge-KrA!MP`)KHdAmxglbR1h*&tIv!!2I9X54UV5W!1%V}BP2Myam0{= zsfn}dn7$OWVEVP71=H<83#Ly7vzUG+n2YI(puuZ@G>T^|>Vn7PKECLSmk??hTTg1v zDBbY8HDEOAT)Nio+!!f347+N$p8I-zVM_{`#&%i8=}mT z3sI&Zecv$FDP-5*8v8da&06S~ScqGZ6w)TAM=74e38b-}?CN1=uX4WKBbY)>z*t;F zg5w?@Rsn$wFEY9h(wzP=Ei!ulj0#x#=e>I@{iEGu>7QTUlkK0M-ILotKe)$OcBU4H zMTLP(x`*%XCjP-`2t(`dK^qpEdO~EKbGPh_#iBD7U!XHQi4X(hLQ@%7gSkfNwYM6`eUft1r3zP9nd&`+&MV^OJ)w}xIN zI$gh44y_qp_2J^f#a_b$Q9-(wm7jRe0jm(G#FYPUKe!1qj?mp`&_Zqyr(NY2+h~6Y zU!cC>ZkD^a@zd^R5qF_z@Iu+(m3bzoX))G2f6U#M&Ohh3bbiKf>HKbgw(~puxt;&I zUtga2kSzVCxow5nwmsoT+v>7y^DSm+QqxxYv#kpFS(-#P8U^^zkS23lwQgjqs{NK$ zm0Md?Y;DyjQ>)G`&TW;p7_CAbY582FsG@GM7}D)Lm${m6E=I%ValP zcUgM2_AX1$R^FBE*|NKGdv?NI=vmZ}c`{v&_rbtx(s=2top)(DRsZKAOV$6r$WnFN zB1_fZU6if*#YMSQe`OJ>MjaMOwwEN?n*S{%*^#&1O!~Y(nDlw8FQ(7SYPKI^Yv>%+ zU6*S1r#z3g3Guf)(Ha^O@wYw6@PT;a0cX@je_he>nM?43yXK%$a9Y_FPmfCayE1_7 zap+6!I}KSqq0ppmzf)o3YD&DnLCgbeh_YtYOANmQ(9*Kn+0dJ5+NbYSSk-*Mu5T`$ zX^@1b)ENwXAEK28$sqU9DB5RSND)`ZJ;-tQorb2_a(}c(bKYsG^KT6bYntcC?e~ux z6t+VqX+3LpYyuB>C(ZBJr8p|M~pXsW;5QqMStujymtfd$}HZ~bDo4Mx56uCc!x48#BFZczdiH< zW@1UQsltg3aivpslzYau3KsFblXr;7qNKguchF`6-hR6U_>tQI{NM%O0LnL?=a}d7 zNPk5b_kG%zeA$g5zwgthxqV_n`CT-Ts2%Deli}eAE7Lx$lyU1#e}f6xr}g<#2WjBr&_Y-M3p} z<^VvC(Z~auYvZJXR`_+&ENORIO% zcQg|au^T2>VsFMPdta!56KnV&2DD~|HsJ%d#JHR$f32@=qdn6NhdKUU_`eSy&Db+% z_+I68;*i`G)PD9&*px(u;d5slPz|4{ZN+D7C2^YC1ma>rVe9;+7xQ7KPO}>pWN9{S zL6&BhFUZnt!U7A;hU-AHotX#}I^kY^#ZV%$@S9j3+{p#rWU#2+x7}vyol|w$nvT|G zYdTn$t!ZDKrKVP{Y5T>`0?quc$IS2G?$*#B9x$^!=`fL59#EKnYj(vTOlRGyV|PTm z`c@t5quM36>aFR}#@?#WvNrAfEgUW|@k?K6YHG=;X}PJU#ip9-Of}V*YO1i-bQ#wKpy{!E;8+sW zV#grA#2ZU(p4JnoqE=`C@s@}<`Dnj|=gx#n+%X{D*RgnvehV z^DtSUAkB*bu_K|+Y2AY!(|+@^6i816w3mJXWljnStOL3O4HWsPNd;&S_qX=bZo9(X z97sC!9Nxy_E05CV9Lj!gUY4>i&C62u>+`ad{o=eVWw*_SbYaC+s*3CnM zSMxADqD`!2h2LsHrqv_KL^y5D!D)&Kr->$1uI zfm-0S5;(P@4?_UA>1L_GTPeC^<%d}XobbqG%f)0{{-J5nG}^l*r@gakv+cdQHrw7yYP0PfYijTLn=S4A^UY{4fTrPC z2~tR#w&-TGyhHom&A@tzdGxkvjdSJbT_U<=$;fUgNS|cC7j4>lh7jNZ%m;*mS^-I| zBJ%)lIWH}EuOjJqhR^$)daC-38E=rxj*sdSGfvc=`a(ha(-L$sgI>&_4-)9b0`%e! zv&tC*^lY}#?Bav5gUN6=D?-?$i72``hoaqcvlQ)^o2BTlneseA; z3ZUW+rLTl`9LeqFEP8i~o!GBi^X$aDGs2xXs`Iudq92;{GKA8dCY0uzP`ciP(lsWO zF0-OEmQeywiz4Pg_0P0_{ziU#$sps|M4Ui)HydW##X@)meajm~xZpyscACmBxIp>Q z!X=w<$do^9OD?L%bmvQ#H>Up4ByX&? z=i6TyHY4qPjLi+s-q{xieAqM%*>q7^K2x{Io#f~4QYk!ps6BV1Y4619;bky~OYF&J znRcV1=nrv7rp(EPAqPwt;>Yk8TYr9$jWN?zZVUyM^eU&NBQ~-9z2ZhWMnsPPgnb>) z=9G8^4tZXlE$8&JVopDsozr-MC8( zJ&CU|ASSA(c?VMiZXCI|<~$EUn4d^wx{C)3Njlp-w+VpZ*leIFY0nh|#1m`km{&IYxRFEd}L9|E)G^Be7ny&oELkduBqJGc11 za&hFlsKaLCe&`=f`j3VA{WZfZSo%Zef%OemG-XYAart?1P3}f~>}-YY`Y7>t)hxN4 z#I6N>P&#b(&z$SJ`Y$yY&|UH!7xy^7H(E48ecA?N={Bw|+=jR0u^*_`8Bf2qvqlky zz&+Z7qIQ@U8ovCzhL;y?(L1v}(xYvtv0(EMW7C;_$);;Tude|-%SF+$fXMDiyr+nZ_l-A+@=etktNmKKT4BRtxl?=X1|`S8mLOARwkWnp7W*C-JA@}% z5FMAr!iNZ-LxxJgXj_N5ZC|anwC$N{w5=okh9W%e<`^H-{@0p+8RtKf{<KZ&66b47mm+roJ`VL$cGG+P5`pR?R z#rsO-`{XI#pgAWiyxE_pC-INmS%bu@cJb&R6efu=zBJIUhWqh^37%u@=f_L@@5Fum z_DAB4?g!D{R_x-z>d;zcxL7IV+bl^NE91c27>R*5(>ON5>+M&4 zOWgRQsW&u18NHPQy#DwHgW7+b9;IYseAdS(^R<8BN6_5 z#ZGF4Wo5l!{X5(r-CwRi7NSKW$Oq5$QSgihj<&`o#^;x8^f;8*nE3os1k7T=2yd`i z`NdMy>FYs@c|9n}>tEr)Sti{^zZROM zb6rjQpP5;Cf#$P|Cw-ItnznG6Fpbs++LVep+^;#VGtFU58<++3do#D-qkR_mOScf9 za8lB3Y%qKD@;{noDSwE|_k5&>1iig&=Jt-X&j*+J>`YU8HSJR~_4f8?qb}NB!Go`* zeR$GuyuUuljBk(ToFx{!nKn^b=S(#D6w7V!JZPBHm*UwfnuY8k*9}wca39?4_p@K% zeqMBKtXA(=JWs!>=$h+EGX>z!&lJlsuQr;txKge*#-d!3MR^*dY`plsdZq>C;7nc- zGmS_qXRvK57>+x&xCQqw4Ck5d>`F8ZM{n6j(8pUrp0DJEDD#Q*jA6K1F)c!x_Ex1O z?^(`!<|BHT`!}*sykt)6%~-o-xaZ|ZRUg6s>pp^C?f+AIoaTp ztapUak+1%ikE%Z>|JILcALBb@F487fh(SmU@bN4pbi9f)l(gd!=8O4{83}LT{|X-b zTYVJ2?bmD-rmchvTZtc5@H)W$o2Iic?^VHQpt$Ik7a>Rl%Hs_1#R^_d(#vep`Bkk1 zxsE}yOTY&!7$isyuL@mKhGlmoVJ|%6;&oIYCv?xCgoiLrPk~}KHgWgG~QTx8D9J;og6DjZ{c&? zlIpXs5@nS4{_@z_3X<>TW8;)(baX7A1tfNgQI!l2NP(D!7EL_eVf+|8KaS-N<1o

+65w8gthC*=TXi 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ǝl|i0Uw~F}i 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. + +#ifndef __PROJECTINFO_H +#define __PROJECTINFO_H + +#define VERSION_INTERNALNAME_STR "sendrpt" +#define VERSION_FILEDESCRIPTION_STR "Report sending utility" + +#include + +#endif// __PROJECTINFO_H diff --git a/ext/CrashServer/CrashHandler/SendRpt/resource.h b/ext/CrashServer/CrashHandler/SendRpt/resource.h new file mode 100644 index 000000000..6548f4eb2 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/resource.h @@ -0,0 +1,36 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by SendRpt.rc +// +#define IDOK 1 +#define IDCANCEL 2 +#define IDR_DBGHELP 101 +#define IDD_SENDREPORTDLG 102 +#define IDI_SENDRPT 102 +#define IDR_DBGHELPX64 102 +#define IDD_ASKSENDFULLDUMPDLG 104 +#define IDD_SENDFULLDUMPDLG 105 +#define IDS_PRIVATE_INFO_TEXT 105 +#define IDS_SOLUTION_URL 106 +#define IDD_SOLUTIONDLG 106 +#define IDS_SOLUTION_EXE 107 +#define IDD_SENDASSERTREPORTDLG 107 +#define IDS_MOTIVATE_TO_SEND_FULL 108 +#define IDS_SENDING_DATA 109 +#define IDC_QUESTION 1001 +#define IDC_HEADER_TEXT 1002 +#define IDC_PROGRESS 1008 +#define IDC_TEXT 1010 +#define IDC_DETAILS 1014 +#define IDC_DETAILS_TEXT 1015 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/ext/CrashServer/CrashHandler/SendRpt/stdafx.cpp b/ext/CrashServer/CrashHandler/SendRpt/stdafx.cpp new file mode 100644 index 000000000..359df47d3 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/stdafx.cpp @@ -0,0 +1,18 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#include "stdafx.h" diff --git a/ext/CrashServer/CrashHandler/SendRpt/stdafx.h b/ext/CrashServer/CrashHandler/SendRpt/stdafx.h new file mode 100644 index 000000000..fcd1e9540 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/stdafx.h @@ -0,0 +1,29 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#include "targetver.h" + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ext/CrashServer/CrashHandler/SendRpt/targetver.h b/ext/CrashServer/CrashHandler/SendRpt/targetver.h new file mode 100644 index 000000000..a00a2ffb0 --- /dev/null +++ b/ext/CrashServer/CrashHandler/SendRpt/targetver.h @@ -0,0 +1,23 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#pragma once + +#define _WIN32_WINNT 0x0501 +#define WINVER 0x0501 + + diff --git a/ext/CrashServer/CrashHandler/crashhandler.props b/ext/CrashServer/CrashHandler/crashhandler.props new file mode 100644 index 000000000..345903a3b --- /dev/null +++ b/ext/CrashServer/CrashHandler/crashhandler.props @@ -0,0 +1,27 @@ + + + + + $(SolutionDir)..\external\ + $(ExternalDir)gsoap-win32-2.8.0 + + + $(SolutionDir)out\$(Platform)\$(Configuration)\ + + + $(SolutionDir)out\$(Platform)\$(Configuration)\temp\$(ProjectName)\ + + + + $(SolutionDir)..\;$(SolutionDir);%(AdditionalIncludeDirectories) + + + + + $(ExternalDir) + + + $(GsoapDir) + + + \ No newline at end of file diff --git a/ext/CrashServer/CrashHandler/crashhandler.sln b/ext/CrashServer/CrashHandler/crashhandler.sln new file mode 100644 index 000000000..11fdb3dc3 --- /dev/null +++ b/ext/CrashServer/CrashHandler/crashhandler.sln @@ -0,0 +1,80 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CrashHandler", "CrashHandler\CrashHandler.vcxproj", "{17308759-20C0-493C-8190-06224DBCFD88}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpUploaderServiceLib", "DumpUploaderServiceLib\DumpUploaderServiceLib.vcxproj", "{EEA8E6F4-76F0-42F7-A139-725C0B368A36}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SendRpt", "SendRpt\SendRpt.vcxproj", "{60557EDD-7D52-4200-8884-7541105387F9}" + ProjectSection(ProjectDependencies) = postProject + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D} = {4137C5C7-7E4D-4071-ADA2-7052550A9E5D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Zlib_static", "..\CommonLibs\Zlib\Zlib_static.vcxproj", "{4137C5C7-7E4D-4071-ADA2-7052550A9E5D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CrashServerSDK", "CrashServerSDK", "{6BCA4F01-15AF-4B1F-9971-695900D20EEA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CommonLibs", "CommonLibs", "{BE3FBB45-E02E-4024-A799-F048C2854360}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SendRptM", "SendRpt\SendRptM.vcxproj", "{944584E3-CE8D-42B6-AEAF-12F44FB15F13}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17308759-20C0-493C-8190-06224DBCFD88}.Debug|Win32.ActiveCfg = Debug|Win32 + {17308759-20C0-493C-8190-06224DBCFD88}.Debug|Win32.Build.0 = Debug|Win32 + {17308759-20C0-493C-8190-06224DBCFD88}.Debug|x64.ActiveCfg = Debug|x64 + {17308759-20C0-493C-8190-06224DBCFD88}.Debug|x64.Build.0 = Debug|x64 + {17308759-20C0-493C-8190-06224DBCFD88}.Release|Win32.ActiveCfg = Release|Win32 + {17308759-20C0-493C-8190-06224DBCFD88}.Release|Win32.Build.0 = Release|Win32 + {17308759-20C0-493C-8190-06224DBCFD88}.Release|x64.ActiveCfg = Release|x64 + {17308759-20C0-493C-8190-06224DBCFD88}.Release|x64.Build.0 = Release|x64 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Debug|Win32.Build.0 = Debug|Win32 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Debug|x64.ActiveCfg = Debug|x64 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Debug|x64.Build.0 = Debug|x64 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Release|Win32.ActiveCfg = Release|Win32 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Release|Win32.Build.0 = Release|Win32 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Release|x64.ActiveCfg = Release|x64 + {EEA8E6F4-76F0-42F7-A139-725C0B368A36}.Release|x64.Build.0 = Release|x64 + {60557EDD-7D52-4200-8884-7541105387F9}.Debug|Win32.ActiveCfg = Debug|Win32 + {60557EDD-7D52-4200-8884-7541105387F9}.Debug|Win32.Build.0 = Debug|Win32 + {60557EDD-7D52-4200-8884-7541105387F9}.Debug|x64.ActiveCfg = Debug|x64 + {60557EDD-7D52-4200-8884-7541105387F9}.Debug|x64.Build.0 = Debug|x64 + {60557EDD-7D52-4200-8884-7541105387F9}.Release|Win32.ActiveCfg = Release|Win32 + {60557EDD-7D52-4200-8884-7541105387F9}.Release|Win32.Build.0 = Release|Win32 + {60557EDD-7D52-4200-8884-7541105387F9}.Release|x64.ActiveCfg = Release|x64 + {60557EDD-7D52-4200-8884-7541105387F9}.Release|x64.Build.0 = Release|x64 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Debug|Win32.Build.0 = Debug|Win32 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Debug|x64.ActiveCfg = Debug|x64 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Debug|x64.Build.0 = Debug|x64 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Release|Win32.ActiveCfg = Release|Win32 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Release|Win32.Build.0 = Release|Win32 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Release|x64.ActiveCfg = Release|x64 + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D}.Release|x64.Build.0 = Release|x64 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Debug|Win32.ActiveCfg = Debug|Win32 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Debug|Win32.Build.0 = Debug|Win32 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Debug|x64.ActiveCfg = Debug|x64 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Debug|x64.Build.0 = Debug|x64 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Release|Win32.ActiveCfg = Release|Win32 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Release|Win32.Build.0 = Release|Win32 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Release|x64.ActiveCfg = Release|x64 + {944584E3-CE8D-42B6-AEAF-12F44FB15F13}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {EEA8E6F4-76F0-42F7-A139-725C0B368A36} = {6BCA4F01-15AF-4B1F-9971-695900D20EEA} + {60557EDD-7D52-4200-8884-7541105387F9} = {6BCA4F01-15AF-4B1F-9971-695900D20EEA} + {17308759-20C0-493C-8190-06224DBCFD88} = {6BCA4F01-15AF-4B1F-9971-695900D20EEA} + {944584E3-CE8D-42B6-AEAF-12F44FB15F13} = {6BCA4F01-15AF-4B1F-9971-695900D20EEA} + {4137C5C7-7E4D-4071-ADA2-7052550A9E5D} = {BE3FBB45-E02E-4024-A799-F048C2854360} + EndGlobalSection +EndGlobal diff --git a/ext/CrashServer/CrashHandler/solutioninfo.h b/ext/CrashServer/CrashHandler/solutioninfo.h new file mode 100644 index 000000000..7146743b5 --- /dev/null +++ b/ext/CrashServer/CrashHandler/solutioninfo.h @@ -0,0 +1,29 @@ +// Copyright 2012 Idol Software, Inc. +// +// This file is part of CrashHandler library. +// +// CrashHandler library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +#ifndef __SOLUTIONINFO_H +#define __SOLUTIONINFO_H + +#define VERSION_PRODUCTNAME_STR "Crash Server" +#define VERSION_PRODUCTVERSION_HIGH 1 +#define VERSION_PRODUCTVERSION_LOW 0 +#define VERSION_PRODUCTVERSION_BUILD 10 +#define VERSION_PRODUCTVERSION_COMPILATION 0 + +#include "CommonLibs\Version\version.h" + +#endif//__SOLUTIONINFO_H diff --git a/ext/CrashServer/Readme.txt b/ext/CrashServer/Readme.txt new file mode 100644 index 000000000..03af35140 --- /dev/null +++ b/ext/CrashServer/Readme.txt @@ -0,0 +1,3 @@ +This is the crash report library code from +http://www.crash-server.com +Licensed under LGPL \ No newline at end of file diff --git a/ext/CrashServer/SymUpload.exe b/ext/CrashServer/SymUpload.exe new file mode 100644 index 0000000000000000000000000000000000000000..98b0385411aee9d1689ae527444cd0c3834f29fb GIT binary patch literal 306176 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
a`ZInDURp~ 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 JPNn}a{U2T06KVhe literal 0 HcwPel00001 diff --git a/ext/CrashServer/external/MiniZip/MiniZip.vcxproj b/ext/CrashServer/external/MiniZip/MiniZip.vcxproj new file mode 100644 index 000000000..c95df7324 --- /dev/null +++ b/ext/CrashServer/external/MiniZip/MiniZip.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9B6FEBB3-70FA-4AD2-B085-3D5CCECE0647} + MiniZip + + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)out_$(Platform)\$(Configuration)\ + $(SolutionDir)out_$(Platform)\$(Configuration)\ + $(SolutionDir)temp_$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)temp_$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)out_$(Platform)\$(Configuration)\ + $(SolutionDir)out_$(Platform)\$(Configuration)\ + $(SolutionDir)temp_$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)temp_$(Platform)\$(Configuration)\$(ProjectName)\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + ..\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Level3 + EditAndContinue + + + true + MachineX86 + + + + + Disabled + ..\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + Level3 + ProgramDatabase + + + true + + + + + MaxSpeed + true + ..\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + + + true + true + true + MachineX86 + + + + + MaxSpeed + true + ..\zlib123;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + + + true + true + true + + + + + + + + {8e75b9c1-d45f-48bc-8c8e-28330e2e12e3} + false + + + + + + \ No newline at end of file diff --git a/ext/CrashServer/external/WTL/CPL.TXT b/ext/CrashServer/external/WTL/CPL.TXT new file mode 100644 index 000000000..e887791df --- /dev/null +++ b/ext/CrashServer/external/WTL/CPL.TXT @@ -0,0 +1,94 @@ +Common Public License Version 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff --git a/ext/CrashServer/external/WTL/Include/atlapp.h b/ext/CrashServer/external/WTL/Include/atlapp.h new file mode 100644 index 000000000..245fef6d3 --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atlapp.h @@ -0,0 +1,1690 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLAPP_H__ +#define __ATLAPP_H__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLBASE_H__ + #error atlapp.h requires atlbase.h to be included first +#endif + +#ifndef _WIN32_WCE + #if (WINVER < 0x0400) + #error WTL requires Windows version 4.0 or higher + #endif + + #if (_WIN32_IE < 0x0300) + #error WTL requires IE version 3.0 or higher + #endif +#endif + +#ifdef _ATL_NO_COMMODULE + #error WTL requires that _ATL_NO_COMMODULE is not defined +#endif // _ATL_NO_COMMODULE + +#if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) + #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT") +#endif // defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) + +#include +#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) + #include // for _beginthreadex +#endif + +#if (_ATL_VER < 0x0800) && !defined(_DEBUG) + #include +#endif + +#include +#ifndef _WIN32_WCE +#pragma comment(lib, "comctl32.lib") +#endif // !_WIN32_WCE + +#ifndef _WIN32_WCE + #include "atlres.h" +#else // CE specific + #include "atlresce.h" +#endif // _WIN32_WCE + +// We need to disable this warning because of template class arguments +#pragma warning(disable: 4127) + + +/////////////////////////////////////////////////////////////////////////////// +// WTL version number + +#define _WTL_VER 0x0810 + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CMessageFilter +// CIdleHandler +// CMessageLoop +// +// CAppModule +// CServerAppModule +// +// Global functions: +// AtlGetDefaultGuiFont() +// AtlCreateBoldFont() +// AtlInitCommonControls() + + +/////////////////////////////////////////////////////////////////////////////// +// Global support for Windows CE + +#ifdef _WIN32_WCE + +#ifndef SW_SHOWDEFAULT + #define SW_SHOWDEFAULT SW_SHOWNORMAL +#endif // !SW_SHOWDEFAULT + +// These get's OR-ed in a constant and will have no effect. +// Defining them reduces the number of #ifdefs required for CE. +#define LR_DEFAULTSIZE 0 +#define LR_LOADFROMFILE 0 + +#ifndef SM_CXCURSOR + #define SM_CXCURSOR 13 +#endif +#ifndef SM_CYCURSOR + #define SM_CYCURSOR 14 +#endif + +inline BOOL IsMenu(HMENU hMenu) +{ + MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; + ::SetLastError(0); + BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii); + if(!bRet) + bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE; + return bRet; +} + +#if (_WIN32_WCE >= 410) +extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight); +#endif // (_WIN32_WCE >= 410) + +inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator) +{ + __int64 multiple = nNumber * nNumerator; + return static_cast(multiple / nDenominator); +} + +#if (_ATL_VER >= 0x0800) + +#ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW + #ifdef WS_OVERLAPPEDWINDOW + #undef WS_OVERLAPPEDWINDOW + #define WS_OVERLAPPEDWINDOW 0 + #endif // WS_OVERLAPPEDWINDOW +#endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW + +#ifndef RDW_FRAME + #define RDW_FRAME 0 +#endif // !RDW_FRAME + +#ifndef WM_WINDOWPOSCHANGING + #define WM_WINDOWPOSCHANGING 0 +#endif // !WM_WINDOWPOSCHANGING + +#define FreeResource(x) +#define UnlockResource(x) + +namespace ATL +{ + inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw() + { return E_NOTIMPL; } + inline HRESULT CComModule::RevokeClassObjects() throw() + { return E_NOTIMPL; } +}; // namespace ATL + +#ifndef lstrlenW + #define lstrlenW (int)ATL::lstrlenW +#endif // lstrlenW + +inline int WINAPI lstrlenA(LPCSTR lpszString) +{ return ATL::lstrlenA(lpszString); } + +#ifdef lstrcpyn + #undef lstrcpyn + #define lstrcpyn ATL::lstrcpynW +#endif // lstrcpyn + +#ifndef SetWindowLongPtrW + inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) + { + return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) ); + } + #define SetWindowLongPtrW tmp_SetWindowLongPtrW +#endif + +#ifndef GetWindowLongPtrW + inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex ) + { + return( ::GetWindowLongW( hWnd, nIndex ) ); + } + #define GetWindowLongPtrW tmp_GetWindowLongPtrW +#endif + +#ifndef LongToPtr + #define LongToPtr(x) ((void*)x) +#endif + +#ifndef PtrToInt + #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) +#endif + +#else // !(_ATL_VER >= 0x0800) + +#ifdef lstrlenW + #undef lstrlenW + #define lstrlenW (int)::wcslen +#endif // lstrlenW + +#define lstrlenA (int)strlen + +#ifndef lstrcpyn + inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength) + { + if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) + return NULL; + int nLen = min(lstrlen(lpstrSrc), nLength - 1); + LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR)); + lpstrDest[nLen] = 0; + return lpstrRet; + } +#endif // !lstrcpyn + +#ifndef lstrcpynW + inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength) + { + return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only + } +#endif // !lstrcpynW + +#ifndef lstrcpynA + inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength) + { + if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) + return NULL; + int nLen = min(lstrlenA(lpstrSrc), nLength - 1); + LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char)); + lpstrDest[nLen] = 0; + return lpstrRet; + } +#endif // !lstrcpyn + +#ifdef TrackPopupMenu + #undef TrackPopupMenu +#endif // TrackPopupMenu + +#define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \ +static CWndClassInfo& GetWndClassInfo() \ +{ \ + static CWndClassInfo wc = \ + { \ + { style, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \ + }; \ + return wc; \ +} + +#ifndef _MAX_FNAME + #define _MAX_FNAME _MAX_PATH +#endif // _MAX_FNAME + +#if (_WIN32_WCE < 400) + #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i))) +#endif // (_WIN32_WCE < 400) + +#if (_WIN32_WCE < 410) + #define WHEEL_PAGESCROLL (UINT_MAX) + #define WHEEL_DELTA 120 +#endif // (_WIN32_WCE < 410) + +#ifdef DrawIcon + #undef DrawIcon +#endif + +#ifndef VARCMP_LT + #define VARCMP_LT 0 +#endif +#ifndef VARCMP_EQ + #define VARCMP_EQ 1 +#endif +#ifndef VARCMP_GT + #define VARCMP_GT 2 +#endif +#ifndef VARCMP_NULL + #define VARCMP_NULL 3 +#endif + +#ifndef RDW_ALLCHILDREN + #define RDW_ALLCHILDREN 0 +#endif + +#endif // !(_ATL_VER >= 0x0800) + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// Global support for using original VC++ 6.0 headers with WTL + +#ifndef _ATL_NO_OLD_HEADERS_WIN64 +#if !defined(_WIN64) && (_ATL_VER < 0x0700) + + #ifndef PSM_INSERTPAGE + #define PSM_INSERTPAGE (WM_USER + 119) + #endif // !PSM_INSERTPAGE + + #ifndef GetClassLongPtr + #define GetClassLongPtrA GetClassLongA + #define GetClassLongPtrW GetClassLongW + #ifdef UNICODE + #define GetClassLongPtr GetClassLongPtrW + #else + #define GetClassLongPtr GetClassLongPtrA + #endif // !UNICODE + #endif // !GetClassLongPtr + + #ifndef GCLP_HICONSM + #define GCLP_HICONSM (-34) + #endif // !GCLP_HICONSM + + #ifndef GetWindowLongPtr + #define GetWindowLongPtrA GetWindowLongA + #define GetWindowLongPtrW GetWindowLongW + #ifdef UNICODE + #define GetWindowLongPtr GetWindowLongPtrW + #else + #define GetWindowLongPtr GetWindowLongPtrA + #endif // !UNICODE + #endif // !GetWindowLongPtr + + #ifndef SetWindowLongPtr + #define SetWindowLongPtrA SetWindowLongA + #define SetWindowLongPtrW SetWindowLongW + #ifdef UNICODE + #define SetWindowLongPtr SetWindowLongPtrW + #else + #define SetWindowLongPtr SetWindowLongPtrA + #endif // !UNICODE + #endif // !SetWindowLongPtr + + #ifndef GWLP_WNDPROC + #define GWLP_WNDPROC (-4) + #endif + #ifndef GWLP_HINSTANCE + #define GWLP_HINSTANCE (-6) + #endif + #ifndef GWLP_HWNDPARENT + #define GWLP_HWNDPARENT (-8) + #endif + #ifndef GWLP_USERDATA + #define GWLP_USERDATA (-21) + #endif + #ifndef GWLP_ID + #define GWLP_ID (-12) + #endif + + #ifndef DWLP_MSGRESULT + #define DWLP_MSGRESULT 0 + #endif + + typedef long LONG_PTR; + typedef unsigned long ULONG_PTR; + typedef ULONG_PTR DWORD_PTR; + + #ifndef HandleToUlong + #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) + #endif + #ifndef HandleToLong + #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) + #endif + #ifndef LongToHandle + #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) + #endif + #ifndef PtrToUlong + #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) + #endif + #ifndef PtrToLong + #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) + #endif + #ifndef PtrToUint + #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) + #endif + #ifndef PtrToInt + #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) + #endif + #ifndef PtrToUshort + #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) + #endif + #ifndef PtrToShort + #define PtrToShort( p ) ((short)(LONG_PTR)(p) ) + #endif + #ifndef IntToPtr + #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i)) + #endif + #ifndef UIntToPtr + #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui)) + #endif + #ifndef LongToPtr + #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l)) + #endif + #ifndef ULongToPtr + #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul)) + #endif + +#endif // !defined(_WIN64) && (_ATL_VER < 0x0700) +#endif // !_ATL_NO_OLD_HEADERS_WIN64 + + +/////////////////////////////////////////////////////////////////////////////// +// Global support for SecureHelper functions + +#ifndef _TRUNCATE + #define _TRUNCATE ((size_t)-1) +#endif + +#ifndef _ERRCODE_DEFINED + #define _ERRCODE_DEFINED + typedef int errno_t; +#endif + +#ifndef _SECURECRT_ERRCODE_VALUES_DEFINED + #define _SECURECRT_ERRCODE_VALUES_DEFINED + #define EINVAL 22 + #define STRUNCATE 80 +#endif + +#ifndef _countof + #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Miscellaneous global support + +// define useful macros from winuser.h +#ifndef IS_INTRESOURCE + #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) +#endif // IS_INTRESOURCE + +// protect template members from windowsx.h macros +#ifdef _INC_WINDOWSX + #undef SubclassWindow +#endif // _INC_WINDOWSX + +// define useful macros from windowsx.h +#ifndef GET_X_LPARAM + #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam)) +#endif +#ifndef GET_Y_LPARAM + #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam)) +#endif + +// Dummy structs for compiling with /CLR +#if (_MSC_VER >= 1300) && defined(_MANAGED) + __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; } + __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; } + __if_not_exists(_PSP::_PSP) { struct _PSP { }; } +#endif + +// Define ATLVERIFY macro for ATL3 +#if (_ATL_VER < 0x0700) + #ifndef ATLVERIFY + #ifdef _DEBUG + #define ATLVERIFY(expr) ATLASSERT(expr) + #else + #define ATLVERIFY(expr) (expr) + #endif // DEBUG + #endif // ATLVERIFY +#endif // (_ATL_VER < 0x0700) + +// Forward declaration for ATL3 fix +#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) + namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); }; +#endif + + +namespace WTL +{ + +#if (_ATL_VER >= 0x0700) + DECLARE_TRACE_CATEGORY(atlTraceUI); + #ifdef _DEBUG + __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI")); + #endif // _DEBUG +#else // !(_ATL_VER >= 0x0700) + enum wtlTraceFlags + { + atlTraceUI = 0x10000000 + }; +#endif // !(_ATL_VER >= 0x0700) + +// Windows version helper +inline bool AtlIsOldWindows() +{ + OSVERSIONINFO ovi = { 0 }; + ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + BOOL bRet = ::GetVersionEx(&ovi); + return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90))); +} + +// default GUI font helper +inline HFONT AtlGetDefaultGuiFont() +{ +#ifndef _WIN32_WCE + return (HFONT)::GetStockObject(DEFAULT_GUI_FONT); +#else // CE specific + return (HFONT)::GetStockObject(SYSTEM_FONT); +#endif // _WIN32_WCE +} + +// bold font helper (NOTE: Caller owns the font, and should destroy it when done using it) +inline HFONT AtlCreateBoldFont(HFONT hFont = NULL) +{ + if(hFont == NULL) + hFont = AtlGetDefaultGuiFont(); + ATLASSERT(hFont != NULL); + HFONT hFontBold = NULL; + LOGFONT lf = { 0 }; + if(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)) + { + lf.lfWeight = FW_BOLD; + hFontBold = ::CreateFontIndirect(&lf); + ATLASSERT(hFontBold != NULL); + } + else + { + ATLASSERT(FALSE); + } + return hFontBold; +} + +// Common Controls initialization helper +inline BOOL AtlInitCommonControls(DWORD dwFlags) +{ + INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags }; + BOOL bRet = ::InitCommonControlsEx(&iccx); + ATLASSERT(bRet); + return bRet; +} + + +/////////////////////////////////////////////////////////////////////////////// +// RunTimeHelper - helper functions for Windows version and structure sizes + +// Not for Windows CE +#if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) + #define _WTL_NO_RUNTIME_STRUCT_SIZE +#endif + +#ifndef _WTL_NO_RUNTIME_STRUCT_SIZE + +#ifndef _SIZEOF_STRUCT + #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) +#endif + +#if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) + #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader) +#endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) + +#if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) + #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign) +#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) + +#if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) + #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns) +#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) + #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st) +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) + +#if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) + #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont) +#endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) + +#endif // !_WTL_NO_RUNTIME_STRUCT_SIZE + +namespace RunTimeHelper +{ +#ifndef _WIN32_WCE + inline bool IsCommCtrl6() + { + DWORD dwMajor = 0, dwMinor = 0; + HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); + return (SUCCEEDED(hRet) && (dwMajor >= 6)); + } + + inline bool IsVista() + { + OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; + BOOL bRet = ::GetVersionEx(&ovi); + return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6)); + } +#endif // !_WIN32_WCE + + inline int SizeOf_REBARBANDINFO() + { + int nSize = sizeof(REBARBANDINFO); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + if(!(IsVista() && IsCommCtrl6())) + nSize = REBARBANDINFO_V6_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + return nSize; + } + +#if (_WIN32_WINNT >= 0x501) + inline int SizeOf_LVGROUP() + { + int nSize = sizeof(LVGROUP); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + if(!IsVista()) + nSize = LVGROUP_V5_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + return nSize; + } + + inline int SizeOf_LVTILEINFO() + { + int nSize = sizeof(LVTILEINFO); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + if(!IsVista()) + nSize = LVTILEINFO_V5_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + return nSize; + } +#endif // (_WIN32_WINNT >= 0x501) + + inline int SizeOf_MCHITTESTINFO() + { + int nSize = sizeof(MCHITTESTINFO); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + if(!(IsVista() && IsCommCtrl6())) + nSize = MCHITTESTINFO_V1_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + return nSize; + } + +#ifndef _WIN32_WCE + inline int SizeOf_NONCLIENTMETRICS() + { + int nSize = sizeof(NONCLIENTMETRICS); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) + if(!IsVista()) + nSize = NONCLIENTMETRICS_V1_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) + return nSize; + } +#endif // !_WIN32_WCE +}; + + +/////////////////////////////////////////////////////////////////////////////// +// ModuleHelper - helper functions for ATL3 and ATL7 module classes + +namespace ModuleHelper +{ + inline HINSTANCE GetModuleInstance() + { +#if (_ATL_VER >= 0x0700) + return ATL::_AtlBaseModule.GetModuleInstance(); +#else // !(_ATL_VER >= 0x0700) + return ATL::_pModule->GetModuleInstance(); +#endif // !(_ATL_VER >= 0x0700) + } + + inline HINSTANCE GetResourceInstance() + { +#if (_ATL_VER >= 0x0700) + return ATL::_AtlBaseModule.GetResourceInstance(); +#else // !(_ATL_VER >= 0x0700) + return ATL::_pModule->GetResourceInstance(); +#endif // !(_ATL_VER >= 0x0700) + } + + inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject) + { +#if (_ATL_VER >= 0x0700) + ATL::_AtlWinModule.AddCreateWndData(pData, pObject); +#else // !(_ATL_VER >= 0x0700) + ATL::_pModule->AddCreateWndData(pData, pObject); +#endif // !(_ATL_VER >= 0x0700) + } + + inline void* ExtractCreateWndData() + { +#if (_ATL_VER >= 0x0700) + return ATL::_AtlWinModule.ExtractCreateWndData(); +#else // !(_ATL_VER >= 0x0700) + return ATL::_pModule->ExtractCreateWndData(); +#endif // !(_ATL_VER >= 0x0700) + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// SecureHelper - helper functions for VS2005 secure CRT + +namespace SecureHelper +{ + inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenA(lpstrSrc)) + ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenW(lpstrSrc)) + ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) + { +#ifdef _UNICODE + strcpyW_x(lpstrDest, cchDest, lpstrSrc); +#else + strcpyA_x(lpstrDest, cchDest, lpstrSrc); +#endif + } + + inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount) + { +#if _SECURE_ATL + return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); +#else + errno_t nRet = 0; + if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) + { + nRet = EINVAL; + } + else if(cchCount == _TRUNCATE) + { + cchCount = min(cchDest - 1, size_t(lstrlenA(lpstrSrc))); + nRet = STRUNCATE; + } + else if(cchDest <= cchCount) + { + lpstrDest[0] = 0; + nRet = EINVAL; + } + if(nRet == 0 || nRet == STRUNCATE) + nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; + ATLASSERT(nRet == 0 || nRet == STRUNCATE); + return nRet; +#endif + } + + inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount) + { +#if _SECURE_ATL + return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); +#else + errno_t nRet = 0; + if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) + { + nRet = EINVAL; + } + else if(cchCount == _TRUNCATE) + { + cchCount = min(cchDest - 1, size_t(lstrlenW(lpstrSrc))); + nRet = STRUNCATE; + } + else if(cchDest <= cchCount) + { + lpstrDest[0] = 0; + nRet = EINVAL; + } + if(nRet == 0 || nRet == STRUNCATE) + nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; + ATLASSERT(nRet == 0 || nRet == STRUNCATE); + return nRet; +#endif + } + + inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount) + { +#ifdef _UNICODE + return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount); +#else + return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount); +#endif + } + + inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenA(lpstrSrc)) + ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenW(lpstrSrc)) + ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) + { +#ifdef _UNICODE + strcatW_x(lpstrDest, cchDest, lpstrSrc); +#else + strcatA_x(lpstrDest, cchDest, lpstrSrc); +#endif + } + + inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) + { +#if _SECURE_ATL + ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc); +#else + if(cbDest >= cbSrc) + memcpy(pDest, pSrc, cbSrc); + else + ATLASSERT(FALSE); +#endif + } + + inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) + { +#if _SECURE_ATL + ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc); +#else + if(cbDest >= cbSrc) + memmove(pDest, pSrc, cbSrc); + else + ATLASSERT(FALSE); +#endif + } + + inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) + { +#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) + return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); +#else + cchBuff; // Avoid unused argument warning +#pragma warning(disable: 4996) + return _vstprintf(lpstrBuff, lpstrFormat, args); +#pragma warning(default: 4996) +#endif + } + + inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) + { +#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) + return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); +#else + cchBuff; // Avoid unused argument warning + return ::wvsprintf(lpstrBuff, lpstrFormat, args); +#endif + } + + inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) + { + va_list args; + va_start(args, lpstrFormat); + int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); + va_end(args); + return nRes; + } + + inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) + { + va_list args; + va_start(args, lpstrFormat); + int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); + va_end(args); + return nRes; + } +}; // namespace SecureHelper + + +/////////////////////////////////////////////////////////////////////////////// +// CMessageFilter - Interface for message filter support + +class CMessageFilter +{ +public: + virtual BOOL PreTranslateMessage(MSG* pMsg) = 0; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CIdleHandler - Interface for idle processing + +class CIdleHandler +{ +public: + virtual BOOL OnIdle() = 0; +}; + +#ifndef _ATL_NO_OLD_NAMES + // for compatilibility with old names only + typedef CIdleHandler CUpdateUIObject; + #define DoUpdate OnIdle +#endif // !_ATL_NO_OLD_NAMES + + +/////////////////////////////////////////////////////////////////////////////// +// CMessageLoop - message loop implementation + +class CMessageLoop +{ +public: + ATL::CSimpleArray m_aMsgFilter; + ATL::CSimpleArray m_aIdleHandler; + MSG m_msg; + +// Message filter operations + BOOL AddMessageFilter(CMessageFilter* pMessageFilter) + { + return m_aMsgFilter.Add(pMessageFilter); + } + + BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter) + { + return m_aMsgFilter.Remove(pMessageFilter); + } + +// Idle handler operations + BOOL AddIdleHandler(CIdleHandler* pIdleHandler) + { + return m_aIdleHandler.Add(pIdleHandler); + } + + BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler) + { + return m_aIdleHandler.Remove(pIdleHandler); + } + +#ifndef _ATL_NO_OLD_NAMES + // for compatilibility with old names only + BOOL AddUpdateUI(CIdleHandler* pIdleHandler) + { + ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); + return AddIdleHandler(pIdleHandler); + } + + BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler) + { + ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); + return RemoveIdleHandler(pIdleHandler); + } +#endif // !_ATL_NO_OLD_NAMES + +// message loop + int Run() + { + BOOL bDoIdle = TRUE; + int nIdleCount = 0; + BOOL bRet; + + for(;;) + { + while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE)) + { + if(!OnIdle(nIdleCount++)) + bDoIdle = FALSE; + } + + bRet = ::GetMessage(&m_msg, NULL, 0, 0); + + if(bRet == -1) + { + ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n")); + continue; // error, don't process + } + else if(!bRet) + { + ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n")); + break; // WM_QUIT, exit message loop + } + + if(!PreTranslateMessage(&m_msg)) + { + ::TranslateMessage(&m_msg); + ::DispatchMessage(&m_msg); + } + + if(IsIdleMessage(&m_msg)) + { + bDoIdle = TRUE; + nIdleCount = 0; + } + } + + return (int)m_msg.wParam; + } + + static BOOL IsIdleMessage(MSG* pMsg) + { + // These messages should NOT cause idle processing + switch(pMsg->message) + { + case WM_MOUSEMOVE: +#ifndef _WIN32_WCE + case WM_NCMOUSEMOVE: +#endif // !_WIN32_WCE + case WM_PAINT: + case 0x0118: // WM_SYSTIMER (caret blink) + return FALSE; + } + + return TRUE; + } + +// Overrideables + // Override to change message filtering + virtual BOOL PreTranslateMessage(MSG* pMsg) + { + // loop backwards + for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--) + { + CMessageFilter* pMessageFilter = m_aMsgFilter[i]; + if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg)) + return TRUE; + } + return FALSE; // not translated + } + + // override to change idle processing + virtual BOOL OnIdle(int /*nIdleCount*/) + { + for(int i = 0; i < m_aIdleHandler.GetSize(); i++) + { + CIdleHandler* pIdleHandler = m_aIdleHandler[i]; + if(pIdleHandler != NULL) + pIdleHandler->OnIdle(); + } + return FALSE; // don't continue + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock +// internal classes to manage critical sections for both ATL3 and ATL7 + +class CStaticDataInitCriticalSectionLock +{ +public: +#if (_ATL_VER >= 0x0700) + ATL::CComCritSecLock m_cslock; + + CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false) + { } +#endif // (_ATL_VER >= 0x0700) + + HRESULT Lock() + { +#if (_ATL_VER >= 0x0700) + return m_cslock.Lock(); +#else // !(_ATL_VER >= 0x0700) + ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit); + return S_OK; +#endif // !(_ATL_VER >= 0x0700) + } + + void Unlock() + { +#if (_ATL_VER >= 0x0700) + m_cslock.Unlock(); +#else // !(_ATL_VER >= 0x0700) + ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit); +#endif // !(_ATL_VER >= 0x0700) + } +}; + + +class CWindowCreateCriticalSectionLock +{ +public: +#if (_ATL_VER >= 0x0700) + ATL::CComCritSecLock m_cslock; + + CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false) + { } +#endif // (_ATL_VER >= 0x0700) + + HRESULT Lock() + { +#if (_ATL_VER >= 0x0700) + return m_cslock.Lock(); +#else // !(_ATL_VER >= 0x0700) + ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate); + return S_OK; +#endif // !(_ATL_VER >= 0x0700) + } + + void Unlock() + { +#if (_ATL_VER >= 0x0700) + m_cslock.Unlock(); +#else // !(_ATL_VER >= 0x0700) + ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate); +#endif // !(_ATL_VER >= 0x0700) + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CTempBuffer - helper class for stack allocations for ATL3 + +#ifndef _WTL_STACK_ALLOC_THRESHOLD + #define _WTL_STACK_ALLOC_THRESHOLD 512 +#endif + +#if (_ATL_VER >= 0x0700) + +using ATL::CTempBuffer; + +#else // !(_ATL_VER >= 0x0700) + +#ifndef SIZE_MAX + #ifdef _WIN64 + #define SIZE_MAX _UI64_MAX + #else + #define SIZE_MAX UINT_MAX + #endif +#endif + +#pragma warning(disable: 4284) // warning for operator -> + +template +class CTempBuffer +{ +public: + CTempBuffer() : m_p(NULL) + { + } + + CTempBuffer(size_t nElements) : m_p(NULL) + { + Allocate(nElements); + } + + ~CTempBuffer() + { + if(m_p != reinterpret_cast(m_abFixedBuffer)) + free(m_p); + } + + operator T*() const + { + return m_p; + } + + T* operator ->() const + { + ATLASSERT(m_p != NULL); + return m_p; + } + + T* Allocate(size_t nElements) + { + ATLASSERT(nElements <= (SIZE_MAX / sizeof(T))); + return AllocateBytes(nElements * sizeof(T)); + } + + T* AllocateBytes(size_t nBytes) + { + ATLASSERT(m_p == NULL); + if(nBytes > t_nFixedBytes) + m_p = static_cast(malloc(nBytes)); + else + m_p = reinterpret_cast(m_abFixedBuffer); + + return m_p; + } + +private: + T* m_p; + BYTE m_abFixedBuffer[t_nFixedBytes]; +}; + +#pragma warning(default: 4284) + +#endif // !(_ATL_VER >= 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// CAppModule - module class for an application + +class CAppModule : public ATL::CComModule +{ +public: + DWORD m_dwMainThreadID; + ATL::CSimpleMap* m_pMsgLoopMap; + ATL::CSimpleArray* m_pSettingChangeNotify; + +// Overrides of CComModule::Init and Term + HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) + { + HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID); + if(FAILED(hRet)) + return hRet; + + m_dwMainThreadID = ::GetCurrentThreadId(); + typedef ATL::CSimpleMap _mapClass; + m_pMsgLoopMap = NULL; + ATLTRY(m_pMsgLoopMap = new _mapClass); + if(m_pMsgLoopMap == NULL) + return E_OUTOFMEMORY; + m_pSettingChangeNotify = NULL; + + return hRet; + } + + void Term() + { + TermSettingChangeNotify(); + delete m_pMsgLoopMap; + CComModule::Term(); + } + +// Message loop map methods + BOOL AddMessageLoop(CMessageLoop* pMsgLoop) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + ATLASSERT(pMsgLoop != NULL); + ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet + + BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop); + + lock.Unlock(); + + return bRet; + } + + BOOL RemoveMessageLoop() + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId()); + + lock.Unlock(); + + return bRet; + } + + CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n")); + ATLASSERT(FALSE); + return NULL; + } + + CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID); + + lock.Unlock(); + + return pLoop; + } + +// Setting change notify methods + // Note: Call this from the main thread for MSDI apps + BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + if(m_pSettingChangeNotify == NULL) + { + typedef ATL::CSimpleArray _notifyClass; + ATLTRY(m_pSettingChangeNotify = new _notifyClass); + ATLASSERT(m_pSettingChangeNotify != NULL); + } + + BOOL bRet = (m_pSettingChangeNotify != NULL); + if(bRet && m_pSettingChangeNotify->GetSize() == 0) + { + // init everything + _ATL_EMPTY_DLGTEMPLATE templ; + HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc); + ATLASSERT(::IsWindow(hNtfWnd)); + if(::IsWindow(hNtfWnd)) + { +// need conditional code because types don't match in winuser.h +#ifdef _WIN64 + ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this); +#else + ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this)); +#endif + bRet = m_pSettingChangeNotify->Add(hNtfWnd); + } + else + { + bRet = FALSE; + } + } + + lock.Unlock(); + + return bRet; + } + + void TermSettingChangeNotify() + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return; + } + + if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->GetSize() > 0) + ::DestroyWindow((*m_pSettingChangeNotify)[0]); + delete m_pSettingChangeNotify; + m_pSettingChangeNotify = NULL; + + lock.Unlock(); + } + + BOOL AddSettingChangeNotify(HWND hWnd) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + ATLASSERT(::IsWindow(hWnd)); + BOOL bRet = FALSE; + if(InitSettingChangeNotify() != FALSE) + bRet = m_pSettingChangeNotify->Add(hWnd); + + lock.Unlock(); + + return bRet; + } + + BOOL RemoveSettingChangeNotify(HWND hWnd) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + BOOL bRet = FALSE; + if(m_pSettingChangeNotify != NULL) + bRet = m_pSettingChangeNotify->Remove(hWnd); + + lock.Unlock(); + + return bRet; + } + +// Implementation - setting change notify dialog template and dialog procedure + struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE + { + _ATL_EMPTY_DLGTEMPLATE() + { + memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE)); + style = WS_POPUP; + } + WORD wMenu, wClass, wTitle; + }; + +#ifdef _WIN64 + static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +#else + static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +#endif + { + if(uMsg == WM_SETTINGCHANGE) + { +// need conditional code because types don't match in winuser.h +#ifdef _WIN64 + CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); +#else + CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); +#endif + ATLASSERT(pModule != NULL); + ATLASSERT(pModule->m_pSettingChangeNotify != NULL); + const UINT uTimeout = 1500; // ms + for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++) + { +#if !defined(_WIN32_WCE) + ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL); +#elif(_WIN32_WCE >= 400) // CE specific + ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL); +#else // _WIN32_WCE < 400 specific + uTimeout; + ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam); +#endif + } + return TRUE; + } + return FALSE; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CServerAppModule - module class for a COM server application + +class CServerAppModule : public CAppModule +{ +public: + HANDLE m_hEventShutdown; + bool m_bActivity; + DWORD m_dwTimeOut; + DWORD m_dwPause; + +// Override of CAppModule::Init + HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) + { + m_dwTimeOut = 5000; + m_dwPause = 1000; + return CAppModule::Init(pObjMap, hInstance, pLibID); + } + + void Term() + { + if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown)) + m_hEventShutdown = NULL; + CAppModule::Term(); + } + +// COM Server methods + LONG Unlock() + { + LONG lRet = CComModule::Unlock(); + if(lRet == 0) + { + m_bActivity = true; + ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero + } + return lRet; + } + + void MonitorShutdown() + { + for(;;) + { + ::WaitForSingleObject(m_hEventShutdown, INFINITE); + DWORD dwWait = 0; + do + { + m_bActivity = false; + dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut); + } + while(dwWait == WAIT_OBJECT_0); + // timed out + if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail + { +#if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE) + ::CoSuspendClassObjects(); + if(!m_bActivity && m_nLockCnt == 0) +#endif + break; + } + } + // This handle should be valid now. If it isn't, + // check if _Module.Term was called first (it shouldn't) + if(::CloseHandle(m_hEventShutdown)) + m_hEventShutdown = NULL; + ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0); + } + + bool StartMonitor() + { + m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL); + if(m_hEventShutdown == NULL) + return false; + DWORD dwThreadID = 0; +#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) + HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID); +#else + HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID); +#endif + bool bRet = (hThread != NULL); + if(bRet) + ::CloseHandle(hThread); + return bRet; + } + + static DWORD WINAPI MonitorProc(void* pv) + { + CServerAppModule* p = (CServerAppModule*)pv; + p->MonitorShutdown(); + return 0; + } + +#if (_ATL_VER < 0x0700) + // search for an occurence of string p2 in string p1 + static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) + { + while(p1 != NULL && *p1 != NULL) + { + LPCTSTR p = p2; + while(p != NULL && *p != NULL) + { + if(*p1 == *p) + return ::CharNext(p1); + p = ::CharNext(p); + } + p1 = ::CharNext(p1); + } + return NULL; + } +#endif // (_ATL_VER < 0x0700) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CString forward reference (enables CString use in atluser.h and atlgdi.h) + +#if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) + #define _WTL_USE_CSTRING +#endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) + +#ifdef _WTL_USE_CSTRING + class CString; // forward declaration (include atlmisc.h for the whole class) +#endif // _WTL_USE_CSTRING + +// CString namespace +#ifndef _CSTRING_NS + #ifdef __ATLSTR_H__ + #define _CSTRING_NS ATL + #else + #define _CSTRING_NS WTL + #endif +#endif // _CSTRING_NS + +// Type classes namespace +#ifndef _WTYPES_NS + #ifdef __ATLTYPES_H__ + #define _WTYPES_NS + #else + #define _WTYPES_NS WTL + #endif +#endif // _WTYPES_NS + +}; // namespace WTL + + +/////////////////////////////////////////////////////////////////////////////// +// General DLL version helpers (excluded from atlbase.h if _ATL_DLL is defined) + +#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) + +namespace ATL +{ + +inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo) +{ + ATLASSERT(pDllVersionInfo != NULL); + if(pDllVersionInfo == NULL) + return E_INVALIDARG; + + // We must get this function explicitly because some DLLs don't implement it. + DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion"); + if(pfnDllGetVersion == NULL) + return E_NOTIMPL; + + return (*pfnDllGetVersion)(pDllVersionInfo); +} + +inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo) +{ + HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName); + if(hInstDLL == NULL) + return E_FAIL; + HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo); + ::FreeLibrary(hInstDLL); + return hRet; +} + +// Common Control Versions: +// Win95/WinNT 4.0 maj=4 min=00 +// IE 3.x maj=4 min=70 +// IE 4.0 maj=4 min=71 +inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) +{ + ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); + if(pdwMajor == NULL || pdwMinor == NULL) + return E_INVALIDARG; + + DLLVERSIONINFO dvi; + ::ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi); + + if(SUCCEEDED(hRet)) + { + *pdwMajor = dvi.dwMajorVersion; + *pdwMinor = dvi.dwMinorVersion; + } + else if(hRet == E_NOTIMPL) + { + // If DllGetVersion is not there, then the DLL is a version + // previous to the one shipped with IE 3.x + *pdwMajor = 4; + *pdwMinor = 0; + hRet = S_OK; + } + + return hRet; +} + +// Shell Versions: +// Win95/WinNT 4.0 maj=4 min=00 +// IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00 +// IE 4.0 with Web Integrated Desktop maj=4 min=71 +// IE 4.01 with Web Integrated Desktop maj=4 min=72 +inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) +{ + ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); + if(pdwMajor == NULL || pdwMinor == NULL) + return E_INVALIDARG; + + DLLVERSIONINFO dvi; + ::ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi); + + if(SUCCEEDED(hRet)) + { + *pdwMajor = dvi.dwMajorVersion; + *pdwMinor = dvi.dwMinorVersion; + } + else if(hRet == E_NOTIMPL) + { + // If DllGetVersion is not there, then the DLL is a version + // previous to the one shipped with IE 4.x + *pdwMajor = 4; + *pdwMinor = 0; + hRet = S_OK; + } + + return hRet; +} + +}; // namespace ATL + +#endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) + + +// These are always included +#include "atlwinx.h" +#include "atluser.h" +#include "atlgdi.h" + +#ifndef _WTL_NO_AUTOMATIC_NAMESPACE +using namespace WTL; +#endif // !_WTL_NO_AUTOMATIC_NAMESPACE + +#endif // __ATLAPP_H__ diff --git a/ext/CrashServer/external/WTL/Include/atlctrls.h b/ext/CrashServer/external/WTL/Include/atlctrls.h new file mode 100644 index 000000000..86d6aeaaa --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atlctrls.h @@ -0,0 +1,10039 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLCTRLS_H__ +#define __ATLCTRLS_H__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLAPP_H__ + #error atlctrls.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlctrls.h requires atlwin.h to be included first +#endif + +#if (_WIN32_IE < 0x0300) + #error atlctrls.h requires IE Version 3.0 or higher +#endif + +#ifndef _WIN32_WCE + #include + #include +#elif defined(WIN32_PLATFORM_WFSP) && !defined(_WINUSERM_H_) + #include +#endif // !_WIN32_WCE + +// protect template members from windowsx.h macros +#ifdef _INC_WINDOWSX + #undef GetNextSibling + #undef GetPrevSibling +#endif // _INC_WINDOWSX + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CStaticT - CStatic +// CButtonT - CButton +// CListBoxT - CListBox +// CComboBoxT - CComboBox +// CEditT - CEdit +// CEditCommands +// CScrollBarT - CScrollBar +// +// CImageList +// CListViewCtrlT - CListViewCtrl +// CTreeViewCtrlT - CTreeViewCtrl +// CTreeItemT - CTreeItem +// CTreeViewCtrlExT - CTreeViewCtrlEx +// CHeaderCtrlT - CHeaderCtrl +// CToolBarCtrlT - CToolBarCtrl +// CStatusBarCtrlT - CStatusBarCtrl +// CTabCtrlT - CTabCtrl +// CToolInfo +// CToolTipCtrlT - CToolTipCtrl +// CTrackBarCtrlT - CTrackBarCtrl +// CUpDownCtrlT - CUpDownCtrl +// CProgressBarCtrlT - CProgressBarCtrl +// CHotKeyCtrlT - CHotKeyCtrl +// CAnimateCtrlT - CAnimateCtrl +// CRichEditCtrlT - CRichEditCtrl +// CRichEditCommands +// CDragListBoxT - CDragListBox +// CDragListNotifyImpl +// CReBarCtrlT - CReBarCtrl +// CComboBoxExT - CComboBoxEx +// CDateTimePickerCtrlT - CDateTimePickerCtrl +// CMonthCalendarCtrlT - CMonthCalendarCtrl +// CFlatScrollBarImpl +// CFlatScrollBarT - CFlatScrollBar +// CIPAddressCtrlT - CIPAddressCtrl +// CPagerCtrlT - CPagerCtrl +// CLinkCtrlT - CLinkCtrl +// +// CCustomDraw +// +// CCECommandBarCtrlT - CCECommandBarCtrl +// CCECommandBandsCtrlT - CCECommandBandsCtrl + + +namespace WTL +{ + +// These are wrapper classes for Windows standard and common controls. +// To implement a window based on a control, use following: +// Example: Implementing a window based on a list box +// +// class CMyListBox : CWindowImpl +// { +// public: +// BEGIN_MSG_MAP(CMyListBox) +// // put your message handler entries here +// END_MSG_MAP() +// }; + + + +// --- Standard Windows controls --- + +/////////////////////////////////////////////////////////////////////////////// +// CStatic - client side for a Windows STATIC control + +template +class CStaticT : public TBase +{ +public: +// Constructors + CStaticT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CStaticT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("STATIC"); + } + +#ifndef _WIN32_WCE + HICON GetIcon() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_GETICON, 0, 0L); + } + + HICON SetIcon(HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_SETICON, (WPARAM)hIcon, 0L); + } + + HENHMETAFILE GetEnhMetaFile() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HENHMETAFILE)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ENHMETAFILE, 0L); + } + + HENHMETAFILE SetEnhMetaFile(HENHMETAFILE hMetaFile) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HENHMETAFILE)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hMetaFile); + } +#else // CE specific + HICON GetIcon() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ICON, 0L); + } + + HICON SetIcon(HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } +#endif // _WIN32_WCE + + CBitmapHandle GetBitmap() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_BITMAP, 0L)); + } + + CBitmapHandle SetBitmap(HBITMAP hBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap)); + } + + HCURSOR GetCursor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_CURSOR, 0L); + } + + HCURSOR SetCursor(HCURSOR hCursor) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor); + } +}; + +typedef CStaticT CStatic; + + +/////////////////////////////////////////////////////////////////////////////// +// CButton - client side for a Windows BUTTON control + +template +class CButtonT : public TBase +{ +public: +// Constructors + CButtonT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CButtonT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("BUTTON"); + } + + UINT GetState() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, BM_GETSTATE, 0, 0L); + } + + void SetState(BOOL bHighlight) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETSTATE, bHighlight, 0L); + } + + int GetCheck() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0L); + } + + void SetCheck(int nCheck) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0L); + } + + UINT GetButtonStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::GetWindowLong(m_hWnd, GWL_STYLE) & 0xFFFF; + } + + void SetButtonStyle(UINT nStyle, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETSTYLE, nStyle, (LPARAM)bRedraw); + } + +#ifndef _WIN32_WCE + HICON GetIcon() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_ICON, 0L); + } + + HICON SetIcon(HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } + + CBitmapHandle GetBitmap() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_BITMAP, 0L)); + } + + CBitmapHandle SetBitmap(HBITMAP hBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap)); + } +#endif // !_WIN32_WCE + +#if (_WIN32_WINNT >= 0x0501) + BOOL GetIdealSize(LPSIZE lpSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_GETIDEALSIZE, 0, (LPARAM)lpSize); + } + + BOOL GetImageList(PBUTTON_IMAGELIST pButtonImagelist) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_GETIMAGELIST, 0, (LPARAM)pButtonImagelist); + } + + BOOL SetImageList(PBUTTON_IMAGELIST pButtonImagelist) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_SETIMAGELIST, 0, (LPARAM)pButtonImagelist); + } + + BOOL GetTextMargin(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_GETTEXTMARGIN, 0, (LPARAM)lpRect); + } + + BOOL SetTextMargin(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_SETTEXTMARGIN, 0, (LPARAM)lpRect); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (WINVER >= 0x0600) + void SetDontClick(BOOL bDontClick) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETDONTCLICK, (WPARAM)bDontClick, 0L); + } +#endif // (WINVER >= 0x0600) + +#if (_WIN32_WINNT >= 0x0600) + BOOL SetDropDownState(BOOL bDropDown) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_SETDROPDOWNSTATE, (WPARAM)bDropDown, 0L); + } + + BOOL GetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_GETSPLITINFO, 0, (LPARAM)pSplitInfo); + } + + BOOL SetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_SETSPLITINFO, 0, (LPARAM)pSplitInfo); + } + + int GetNoteLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); + return (int)::SendMessage(m_hWnd, BCM_GETNOTELENGTH, 0, 0L); + } + + BOOL GetNote(LPWSTR lpstrNoteText, int cchNoteText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_GETNOTE, cchNoteText, (LPARAM)lpstrNoteText); + } + + BOOL SetNote(LPCWSTR lpstrNoteText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_SETNOTE, 0, (LPARAM)lpstrNoteText); + } + + LRESULT SetElevationRequiredState(BOOL bSet) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SendMessage(m_hWnd, BCM_SETSHIELD, 0, (LPARAM)bSet); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + void Click() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_CLICK, 0, 0L); + } +}; + +typedef CButtonT CButton; + + +/////////////////////////////////////////////////////////////////////////////// +// CListBox - client side for a Windows LISTBOX control + +template +class CListBoxT : public TBase +{ +public: +// Constructors + CListBoxT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CListBoxT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("LISTBOX"); + } + + // for entire listbox + int GetCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0L); + } + +#ifndef _WIN32_WCE + int SetCount(int cItems) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LBS_NODATA) != 0) && ((GetStyle() & LBS_HASSTRINGS) == 0)); + return (int)::SendMessage(m_hWnd, LB_SETCOUNT, cItems, 0L); + } +#endif // !_WIN32_WCE + + int GetHorizontalExtent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETHORIZONTALEXTENT, 0, 0L); + } + + void SetHorizontalExtent(int cxExtent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LB_SETHORIZONTALEXTENT, cxExtent, 0L); + } + + int GetTopIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETTOPINDEX, 0, 0L); + } + + int SetTopIndex(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETTOPINDEX, nIndex, 0L); + } + + LCID GetLocale() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, LB_GETLOCALE, 0, 0L); + } + + LCID SetLocale(LCID nNewLocale) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, LB_SETLOCALE, (WPARAM)nNewLocale, 0L); + } + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + DWORD GetListBoxInfo() const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_WIN32_WINNT >= 0x0501) + return (DWORD)::SendMessage(m_hWnd, LB_GETLISTBOXINFO, 0, 0L); +#else // !(_WIN32_WINNT >= 0x0501) + return ::GetListBoxInfo(m_hWnd); +#endif // !(_WIN32_WINNT >= 0x0501) + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + + // for single-selection listboxes + int GetCurSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); + return (int)::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0L); + } + + int SetCurSel(int nSelect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); + return (int)::SendMessage(m_hWnd, LB_SETCURSEL, nSelect, 0L); + } + + // for multiple-selection listboxes + int GetSel(int nIndex) const // also works for single-selection + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETSEL, nIndex, 0L); + } + + int SetSel(int nIndex, BOOL bSelect = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_SETSEL, bSelect, nIndex); + } + + int GetSelCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_GETSELCOUNT, 0, 0L); + } + + int GetSelItems(int nMaxItems, LPINT rgIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_GETSELITEMS, nMaxItems, (LPARAM)rgIndex); + } + + int GetAnchorIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_GETANCHORINDEX, 0, 0L); + } + + void SetAnchorIndex(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + ::SendMessage(m_hWnd, LB_SETANCHORINDEX, nIndex, 0L); + } + + int GetCaretIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETCARETINDEX, 0, 0); + } + + int SetCaretIndex(int nIndex, BOOL bScroll = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETCARETINDEX, nIndex, MAKELONG(bScroll, 0)); + } + + // for listbox items + DWORD_PTR GetItemData(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD_PTR)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L); + } + + int SetItemData(int nIndex, DWORD_PTR dwItemData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETITEMDATA, nIndex, (LPARAM)dwItemData); + } + + void* GetItemDataPtr(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (void*)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L); + } + + int SetItemDataPtr(int nIndex, void* pData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItemData(nIndex, (DWORD_PTR)pData); + } + + int GetItemRect(int nIndex, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETITEMRECT, nIndex, (LPARAM)lpRect); + } + + int GetText(int nIndex, LPTSTR lpszBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETTEXT, nIndex, (LPARAM)lpszBuffer); + } + +#ifndef _ATL_NO_COM +#ifdef _OLEAUTO_H_ + BOOL GetTextBSTR(int nIndex, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + int nLen = GetTextLen(nIndex); + if(nLen == LB_ERR) + return FALSE; + + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLen + 1); + if(lpstrText == NULL) + return FALSE; + + if(GetText(nIndex, lpstrText) == LB_ERR) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpstrText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // _OLEAUTO_H_ +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetText(int nIndex, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int cchLen = GetTextLen(nIndex); + if(cchLen == LB_ERR) + return LB_ERR; + int nRet = LB_ERR; + LPTSTR lpstr = strText.GetBufferSetLength(cchLen); + if(lpstr != NULL) + { + nRet = GetText(nIndex, lpstr); + strText.ReleaseBuffer(); + } + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + int GetTextLen(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETTEXTLEN, nIndex, 0L); + } + + int GetItemHeight(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETITEMHEIGHT, nIndex, 0L); + } + + int SetItemHeight(int nIndex, UINT cyItemHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0)); + } + + // Settable only attributes + void SetColumnWidth(int cxWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LB_SETCOLUMNWIDTH, cxWidth, 0L); + } + + BOOL SetTabStops(int nTabStops, LPINT rgTabStops) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); + return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); + } + + BOOL SetTabStops() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); + return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 0, 0L); + } + + BOOL SetTabStops(const int& cxEachStop) // takes an 'int' + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); + return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); + } + +// Operations + int InitStorage(int nItems, UINT nBytes) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_INITSTORAGE, (WPARAM)nItems, nBytes); + } + + void ResetContent() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LB_RESETCONTENT, 0, 0L); + } + + UINT ItemFromPoint(POINT pt, BOOL& bOutside) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dw = (DWORD)::SendMessage(m_hWnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y)); + bOutside = (BOOL)HIWORD(dw); + return (UINT)LOWORD(dw); + } + + // manipulating listbox items + int AddString(LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem); + } + + int DeleteString(UINT nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_DELETESTRING, nIndex, 0L); + } + + int InsertString(int nIndex, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_INSERTSTRING, nIndex, (LPARAM)lpszItem); + } + +#ifndef _WIN32_WCE + int Dir(UINT attr, LPCTSTR lpszWildCard) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_DIR, attr, (LPARAM)lpszWildCard); + } + + int AddFile(LPCTSTR lpstrFileName) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_ADDFILE, 0, (LPARAM)lpstrFileName); + } +#endif // !_WIN32_WCE + + // selection helpers + int FindString(int nStartAfter, LPCTSTR lpszItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_FINDSTRING, nStartAfter, (LPARAM)lpszItem); + } + + int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind); + } + + int SelectString(int nStartAfter, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SELECTSTRING, nStartAfter, (LPARAM)lpszItem); + } + + int SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + ATLASSERT(nFirstItem <= nLastItem); + return bSelect ? (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nFirstItem, nLastItem) : (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nLastItem, nFirstItem); + } + +#ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages + DWORD GetInputMode(BOOL bCurrentMode = TRUE) + { + return SendMessage(LB_GETINPUTMODE, 0, (LPARAM)bCurrentMode); + } + + BOOL SetInputMode(DWORD dwMode) + { + return SendMessage(LB_SETINPUTMODE, 0, (LPARAM)dwMode); + } +#endif // WIN32_PLATFORM_WFSP +}; + +typedef CListBoxT CListBox; + + +/////////////////////////////////////////////////////////////////////////////// +// CComboBox - client side for a Windows COMBOBOX control + +#ifndef WIN32_PLATFORM_WFSP // No COMBOBOX on SmartPhones + +template +class CComboBoxT : public TBase +{ +public: +// Constructors + CComboBoxT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CComboBoxT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("COMBOBOX"); + } + + // for entire combo box + int GetCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0L); + } + + int GetCurSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0L); + } + + int SetCurSel(int nSelect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETCURSEL, nSelect, 0L); + } + + LCID GetLocale() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, CB_GETLOCALE, 0, 0L); + } + + LCID SetLocale(LCID nNewLocale) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, CB_SETLOCALE, (WPARAM)nNewLocale, 0L); + } + + int GetTopIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETTOPINDEX, 0, 0L); + } + + int SetTopIndex(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETTOPINDEX, nIndex, 0L); + } + + UINT GetHorizontalExtent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, CB_GETHORIZONTALEXTENT, 0, 0L); + } + + void SetHorizontalExtent(UINT nExtent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_SETHORIZONTALEXTENT, nExtent, 0L); + } + + int GetDroppedWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETDROPPEDWIDTH, 0, 0L); + } + + int SetDroppedWidth(UINT nWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETDROPPEDWIDTH, nWidth, 0L); + } + +#if ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + BOOL GetComboBoxInfo(PCOMBOBOXINFO pComboBoxInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if ((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + return (BOOL)::SendMessage(m_hWnd, CB_GETCOMBOBOXINFO, 0, (LPARAM)pComboBoxInfo); +#else // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + return ::GetComboBoxInfo(m_hWnd, pComboBoxInfo); +#endif // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + } +#endif // ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + + // for edit control + DWORD GetEditSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, CB_GETEDITSEL, 0, 0L); + } + + BOOL SetEditSel(int nStartChar, int nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_SETEDITSEL, 0, MAKELONG(nStartChar, nEndChar)); + } + + // for combobox item + DWORD_PTR GetItemData(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD_PTR)::SendMessage(m_hWnd, CB_GETITEMDATA, nIndex, 0L); + } + + int SetItemData(int nIndex, DWORD_PTR dwItemData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETITEMDATA, nIndex, (LPARAM)dwItemData); + } + + void* GetItemDataPtr(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (void*)GetItemData(nIndex); + } + + int SetItemDataPtr(int nIndex, void* pData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItemData(nIndex, (DWORD_PTR)pData); + } + + int GetLBText(int nIndex, LPTSTR lpszText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETLBTEXT, nIndex, (LPARAM)lpszText); + } + +#ifndef _ATL_NO_COM + BOOL GetLBTextBSTR(int nIndex, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + int nLen = GetLBTextLen(nIndex); + if(nLen == CB_ERR) + return FALSE; + + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLen + 1); + if(lpstrText == NULL) + return FALSE; + + if(GetLBText(nIndex, lpstrText) == CB_ERR) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpstrText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetLBText(int nIndex, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int cchLen = GetLBTextLen(nIndex); + if(cchLen == CB_ERR) + return CB_ERR; + int nRet = CB_ERR; + LPTSTR lpstr = strText.GetBufferSetLength(cchLen); + if(lpstr != NULL) + { + nRet = GetLBText(nIndex, lpstr); + strText.ReleaseBuffer(); + } + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + int GetLBTextLen(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETLBTEXTLEN, nIndex, 0L); + } + + int GetItemHeight(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETITEMHEIGHT, nIndex, 0L); + } + + int SetItemHeight(int nIndex, UINT cyItemHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0)); + } + + BOOL GetExtendedUI() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_GETEXTENDEDUI, 0, 0L); + } + + int SetExtendedUI(BOOL bExtended = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETEXTENDEDUI, bExtended, 0L); + } + + void GetDroppedControlRect(LPRECT lprect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)lprect); + } + + BOOL GetDroppedState() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_GETDROPPEDSTATE, 0, 0L); + } + +#if (_WIN32_WINNT >= 0x0501) + int GetMinVisible() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETMINVISIBLE, 0, 0L); + } + + BOOL SetMinVisible(int nMinVisible) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_SETMINVISIBLE, nMinVisible, 0L); + } + + // Vista only + BOOL GetCueBannerText(LPWSTR lpwText, int cchText) const + { +#ifndef CB_GETCUEBANNER + const UINT CB_GETCUEBANNER = (CBM_FIRST + 4); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_GETCUEBANNER, (WPARAM)lpwText, cchText); + } + + // Vista only + BOOL SetCueBannerText(LPCWSTR lpcwText) + { +#ifndef CB_SETCUEBANNER + const UINT CB_SETCUEBANNER = (CBM_FIRST + 3); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_SETCUEBANNER, 0, (LPARAM)lpcwText); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + int InitStorage(int nItems, UINT nBytes) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_INITSTORAGE, (WPARAM)nItems, nBytes); + } + + void ResetContent() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0L); + } + + // for edit control + BOOL LimitText(int nMaxChars) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_LIMITTEXT, nMaxChars, 0L); + } + + // for drop-down combo boxes + void ShowDropDown(BOOL bShowIt = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_SHOWDROPDOWN, bShowIt, 0L); + } + + // manipulating listbox items + int AddString(LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)lpszString); + } + + int DeleteString(UINT nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_DELETESTRING, nIndex, 0L); + } + + int InsertString(int nIndex, LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_INSERTSTRING, nIndex, (LPARAM)lpszString); + } + +#ifndef _WIN32_WCE + int Dir(UINT attr, LPCTSTR lpszWildCard) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_DIR, attr, (LPARAM)lpszWildCard); + } +#endif // !_WIN32_WCE + + // selection helpers + int FindString(int nStartAfter, LPCTSTR lpszString) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_FINDSTRING, nStartAfter, (LPARAM)lpszString); + } + + int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind); + } + + int SelectString(int nStartAfter, LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SELECTSTRING, nStartAfter, (LPARAM)lpszString); + } + + // Clipboard operations + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } +}; + +typedef CComboBoxT CComboBox; + +#endif // !WIN32_PLATFORM_WFSP + +/////////////////////////////////////////////////////////////////////////////// +// CEdit - client side for a Windows EDIT control + +template +class CEditT : public TBase +{ +public: +// Constructors + CEditT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CEditT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("EDIT"); + } + + BOOL CanUndo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); + } + + int GetLineCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L); + } + + BOOL GetModify() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); + } + + void SetModify(BOOL bModified = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L); + } + + void GetRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect); + } + + DWORD GetSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L); + } + + void GetSel(int& nStartChar, int& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); + } + +#ifndef _WIN32_WCE + HLOCAL GetHandle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HLOCAL)::SendMessage(m_hWnd, EM_GETHANDLE, 0, 0L); + } + + void SetHandle(HLOCAL hBuffer) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETHANDLE, (WPARAM)hBuffer, 0L); + } +#endif // !_WIN32_WCE + + DWORD GetMargins() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETMARGINS, 0, 0L); + } + + void SetMargins(UINT nLeft, UINT nRight) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(nLeft, nRight)); + } + + UINT GetLimitText() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L); + } + + void SetLimitText(UINT nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETLIMITTEXT, nMax, 0L); + } + + POINT PosFromChar(UINT nChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_POSFROMCHAR, nChar, 0); + POINT point = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) }; + return point; + } + + int CharFromPos(POINT pt, int* pLine = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y)); + if(pLine != NULL) + *pLine = (int)(short)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + // NOTE: first word in lpszBuffer must contain the size of the buffer! + int GetLine(int nIndex, LPTSTR lpszBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + *(LPWORD)lpszBuffer = (WORD)nMaxLength; + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + TCHAR GetPasswordChar() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (TCHAR)::SendMessage(m_hWnd, EM_GETPASSWORDCHAR, 0, 0L); + } + + void SetPasswordChar(TCHAR ch) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETPASSWORDCHAR, ch, 0L); + } + +#ifndef _WIN32_WCE + EDITWORDBREAKPROC GetWordBreakProc() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (EDITWORDBREAKPROC)::SendMessage(m_hWnd, EM_GETWORDBREAKPROC, 0, 0L); + } + + void SetWordBreakProc(EDITWORDBREAKPROC ewbprc) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, (LPARAM)ewbprc); + } +#endif // !_WIN32_WCE + + int GetFirstVisibleLine() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L); + } + +#ifndef _WIN32_WCE + int GetThumb() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & ES_MULTILINE) != 0); + return (int)::SendMessage(m_hWnd, EM_GETTHUMB, 0, 0L); + } +#endif // !_WIN32_WCE + + BOOL SetReadOnly(BOOL bReadOnly = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L); + } + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + UINT GetImeStatus(UINT uStatus) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETIMESTATUS, uStatus, 0L); + } + + UINT SetImeStatus(UINT uStatus, UINT uData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_SETIMESTATUS, uStatus, uData); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + BOOL GetCueBannerText(LPCWSTR lpstrText, int cchText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETCUEBANNER, (WPARAM)lpstrText, cchText); + } + + // bKeepWithFocus - Vista only + BOOL SetCueBannerText(LPCWSTR lpstrText, BOOL bKeepWithFocus = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETCUEBANNER, (WPARAM)bKeepWithFocus, (LPARAM)(lpstrText)); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + void EmptyUndoBuffer() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L); + } + + BOOL FmtLines(BOOL bAddEOL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_FMTLINES, bAddEOL, 0L); + } + + void LimitText(int nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_LIMITTEXT, nChars, 0L); + } + + int LineFromChar(int nIndex = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINEFROMCHAR, nIndex, 0L); + } + + int LineIndex(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L); + } + + int LineLength(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L); + } + + void LineScroll(int nLines, int nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines); + } + + void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText); + } + + void SetRect(LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect); + } + + void SetRectNP(LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETRECTNP, 0, (LPARAM)lpRect); + } + + void SetSel(DWORD dwSelection, BOOL bNoScroll = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETSEL, LOWORD(dwSelection), HIWORD(dwSelection)); + if(!bNoScroll) + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar); + if(!bNoScroll) + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + void SetSelAll(BOOL bNoScroll = FALSE) + { + SetSel(0, -1, bNoScroll); + } + + void SetSelNone(BOOL bNoScroll = FALSE) + { + SetSel(-1, 0, bNoScroll); + } + + BOOL SetTabStops(int nTabStops, LPINT rgTabStops) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); + } + + BOOL SetTabStops() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L); + } + + BOOL SetTabStops(const int& cxEachStop) // takes an 'int' + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); + } + + void ScrollCaret() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + int Scroll(int nScrollAction) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & ES_MULTILINE) != 0); + LRESULT lRet = ::SendMessage(m_hWnd, EM_SCROLL, nScrollAction, 0L); + if(!(BOOL)HIWORD(lRet)) + return -1; // failed + return (int)(short)LOWORD(lRet); + + } + + void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE) + { + SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll); + ReplaceSel(lpstrText, bCanUndo); + } + + void AppendText(LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE) + { + InsertText(GetWindowTextLength(), lpstrText, bNoScroll, bCanUndo); + } + +#if (_WIN32_WINNT >= 0x0501) + BOOL ShowBalloonTip(PEDITBALLOONTIP pEditBaloonTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SHOWBALLOONTIP, 0, (LPARAM)pEditBaloonTip); + } + + BOOL HideBalloonTip() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_HIDEBALLOONTIP, 0, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + DWORD GetHilite() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L); + } + + void GetHilite(int& nStartChar, int& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L); + nStartChar = (int)(short)LOWORD(dwRet); + nEndChar = (int)(short)HIWORD(dwRet); + } + + void SetHilite(int nStartChar, int nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETHILITE, nStartChar, nEndChar); + } +#endif // (_WIN32_WINNT >= 0x0600) + + // Clipboard operations + BOOL Undo() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L); + } + + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } + +#ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages + DWORD GetExtendedStyle() + { + return SendMessage(EM_GETEXTENDEDSTYLE); + } + + DWORD SetExtendedStyle(DWORD dwMask, DWORD dwExStyle) + { + return SendMessage(EM_SETEXTENDEDSTYLE, (WPARAM)dwMask, (LPARAM)dwExStyle); + } + + DWORD GetInputMode(BOOL bCurrentMode = TRUE) + { + return SendMessage(EM_GETINPUTMODE, 0, (LPARAM)bCurrentMode); + } + + BOOL SetInputMode(DWORD dwMode) + { + return SendMessage(EM_SETINPUTMODE, 0, (LPARAM)dwMode); + } + + BOOL SetSymbols(LPCTSTR szSymbols) + { + return SendMessage(EM_SETSYMBOLS, 0, (LPARAM)szSymbols); + } + + BOOL ResetSymbols() + { + return SendMessage(EM_SETSYMBOLS); + } +#endif // WIN32_PLATFORM_WFSP +}; + +typedef CEditT CEdit; + + +/////////////////////////////////////////////////////////////////////////////// +// CEditCommands - message handlers for standard EDIT commands + +// Chain to CEditCommands message map. Your class must also derive from CEdit. +// Example: +// class CMyEdit : public CWindowImpl, +// public CEditCommands +// { +// public: +// BEGIN_MSG_MAP(CMyEdit) +// // your handlers... +// CHAIN_MSG_MAP_ALT(CEditCommands, 1) +// END_MSG_MAP() +// // other stuff... +// }; + +template +class CEditCommands +{ +public: + BEGIN_MSG_MAP(CEditCommands< T >) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR, OnEditClear) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, OnEditClearAll) + COMMAND_ID_HANDLER(ID_EDIT_COPY, OnEditCopy) + COMMAND_ID_HANDLER(ID_EDIT_CUT, OnEditCut) + COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnEditPaste) + COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnEditSelectAll) + COMMAND_ID_HANDLER(ID_EDIT_UNDO, OnEditUndo) + END_MSG_MAP() + + LRESULT OnEditClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Clear(); + return 0; + } + + LRESULT OnEditClearAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->SetSel(0, -1); + pT->Clear(); + return 0; + } + + LRESULT OnEditCopy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Copy(); + return 0; + } + + LRESULT OnEditCut(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Cut(); + return 0; + } + + LRESULT OnEditPaste(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Paste(); + return 0; + } + + LRESULT OnEditSelectAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->SetSel(0, -1); + return 0; + } + + LRESULT OnEditUndo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Undo(); + return 0; + } + +// State (update UI) helpers + BOOL CanCut() const + { return HasSelection(); } + + BOOL CanCopy() const + { return HasSelection(); } + + BOOL CanClear() const + { return HasSelection(); } + + BOOL CanSelectAll() const + { return HasText(); } + + BOOL CanFind() const + { return HasText(); } + + BOOL CanRepeat() const + { return HasText(); } + + BOOL CanReplace() const + { return HasText(); } + + BOOL CanClearAll() const + { return HasText(); } + +// Implementation + BOOL HasSelection() const + { + const T* pT = static_cast(this); + int nMin, nMax; + ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nMin, (LPARAM)&nMax); + return (nMin != nMax); + } + + BOOL HasText() const + { + const T* pT = static_cast(this); + return (pT->GetWindowTextLength() > 0); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CScrollBar - client side for a Windows SCROLLBAR control + +template +class CScrollBarT : public TBase +{ +public: +// Constructors + CScrollBarT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CScrollBarT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("SCROLLBAR"); + } + +#ifndef _WIN32_WCE + int GetScrollPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::GetScrollPos(m_hWnd, SB_CTL); + } +#endif // !_WIN32_WCE + + int SetScrollPos(int nPos, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetScrollPos(m_hWnd, SB_CTL, nPos, bRedraw); + } + +#ifndef _WIN32_WCE + void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::GetScrollRange(m_hWnd, SB_CTL, lpMinPos, lpMaxPos); + } +#endif // !_WIN32_WCE + + void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SetScrollRange(m_hWnd, SB_CTL, nMinPos, nMaxPos, bRedraw); + } + + BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::GetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo); + } + + int SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo, bRedraw); + } + +#ifndef _WIN32_WCE + int GetScrollLimit() const + { + int nMin = 0, nMax = 0; + ::GetScrollRange(m_hWnd, SB_CTL, &nMin, &nMax); + SCROLLINFO info = { 0 }; + info.cbSize = sizeof(SCROLLINFO); + info.fMask = SIF_PAGE; + if(::GetScrollInfo(m_hWnd, SB_CTL, &info)) + nMax -= ((info.nPage - 1) > 0) ? (info.nPage - 1) : 0; + + return nMax; + } + +#if (WINVER >= 0x0500) + BOOL GetScrollBarInfo(PSCROLLBARINFO pScrollBarInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_WIN32_WINNT >= 0x0501) + return (BOOL)::SendMessage(m_hWnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)pScrollBarInfo); +#else // !(_WIN32_WINNT >= 0x0501) + return ::GetScrollBarInfo(m_hWnd, OBJID_CLIENT, pScrollBarInfo); +#endif // !(_WIN32_WINNT >= 0x0501) + } +#endif // (WINVER >= 0x0500) + +// Operations + void ShowScrollBar(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::ShowScrollBar(m_hWnd, SB_CTL, bShow); + } + + BOOL EnableScrollBar(UINT nArrowFlags = ESB_ENABLE_BOTH) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::EnableScrollBar(m_hWnd, SB_CTL, nArrowFlags); + } +#endif // !_WIN32_WCE +}; + +typedef CScrollBarT CScrollBar; + + +// --- Windows Common Controls --- + +/////////////////////////////////////////////////////////////////////////////// +// CImageList + +class CImageList +{ +public: + HIMAGELIST m_hImageList; + +// Constructor + CImageList(HIMAGELIST hImageList = NULL) : m_hImageList(hImageList) + { } + +// Operators, etc. + CImageList& operator =(HIMAGELIST hImageList) + { + m_hImageList = hImageList; + return *this; + } + + operator HIMAGELIST() const { return m_hImageList; } + + void Attach(HIMAGELIST hImageList) + { + ATLASSERT(m_hImageList == NULL); + ATLASSERT(hImageList != NULL); + m_hImageList = hImageList; + } + + HIMAGELIST Detach() + { + HIMAGELIST hImageList = m_hImageList; + m_hImageList = NULL; + return hImageList; + } + + bool IsNull() const { return (m_hImageList == NULL); } + +// Attributes + int GetImageCount() const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetImageCount(m_hImageList); + } + + COLORREF GetBkColor() const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetBkColor(m_hImageList); + } + + COLORREF SetBkColor(COLORREF cr) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetBkColor(m_hImageList, cr); + } + + BOOL GetImageInfo(int nImage, IMAGEINFO* pImageInfo) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetImageInfo(m_hImageList, nImage, pImageInfo); + } + + HICON GetIcon(int nIndex, UINT uFlags = ILD_NORMAL) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetIcon(m_hImageList, nIndex, uFlags); + } + + BOOL GetIconSize(int& cx, int& cy) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetIconSize(m_hImageList, &cx, &cy); + } + + BOOL GetIconSize(SIZE& size) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetIconSize(m_hImageList, (int*)&size.cx, (int*)&size.cy); + } + + BOOL SetIconSize(int cx, int cy) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetIconSize(m_hImageList, cx, cy); + } + + BOOL SetIconSize(SIZE size) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetIconSize(m_hImageList, size.cx, size.cy); + } + + BOOL SetImageCount(UINT uNewCount) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetImageCount(m_hImageList, uNewCount); + } + + BOOL SetOverlayImage(int nImage, int nOverlay) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetOverlayImage(m_hImageList, nImage, nOverlay); + } + +// Operations + BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_Create(cx, cy, nFlags, nInitial, nGrow); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + + BOOL Create(ATL::_U_STRINGorID bitmap, int cx, int nGrow, COLORREF crMask) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, cx, nGrow, crMask); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + + BOOL CreateFromImage(ATL::_U_STRINGorID image, int cx, int nGrow, COLORREF crMask, UINT uType, UINT uFlags = LR_DEFAULTCOLOR | LR_DEFAULTSIZE) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, cx, nGrow, crMask, uType, uFlags); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + + BOOL Merge(HIMAGELIST hImageList1, int nImage1, HIMAGELIST hImageList2, int nImage2, int dx, int dy) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_Merge(hImageList1, nImage1, hImageList2, nImage2, dx, dy); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + +#ifndef _WIN32_WCE +#ifdef __IStream_INTERFACE_DEFINED__ + BOOL CreateFromStream(LPSTREAM lpStream) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_Read(lpStream); + return (m_hImageList != NULL) ? TRUE : FALSE; + } +#endif // __IStream_INTERFACE_DEFINED__ +#endif // !_WIN32_WCE + + BOOL Destroy() + { + if (m_hImageList == NULL) + return FALSE; + BOOL bRet = ImageList_Destroy(m_hImageList); + if(bRet) + m_hImageList = NULL; + return bRet; + } + + int Add(HBITMAP hBitmap, HBITMAP hBitmapMask = NULL) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Add(m_hImageList, hBitmap, hBitmapMask); + } + + int Add(HBITMAP hBitmap, COLORREF crMask) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_AddMasked(m_hImageList, hBitmap, crMask); + } + + BOOL Remove(int nImage) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Remove(m_hImageList, nImage); + } + + BOOL RemoveAll() + { + ATLASSERT(m_hImageList != NULL); + return ImageList_RemoveAll(m_hImageList); + } + + BOOL Replace(int nImage, HBITMAP hBitmap, HBITMAP hBitmapMask) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Replace(m_hImageList, nImage, hBitmap, hBitmapMask); + } + + int AddIcon(HICON hIcon) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_AddIcon(m_hImageList, hIcon); + } + + int ReplaceIcon(int nImage, HICON hIcon) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_ReplaceIcon(m_hImageList, nImage, hIcon); + } + + HICON ExtractIcon(int nImage) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_ExtractIcon(NULL, m_hImageList, nImage); + } + + BOOL Draw(HDC hDC, int nImage, int x, int y, UINT nStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_Draw(m_hImageList, nImage, hDC, x, y, nStyle); + } + + BOOL Draw(HDC hDC, int nImage, POINT pt, UINT nStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_Draw(m_hImageList, nImage, hDC, pt.x, pt.y, nStyle); + } + + BOOL DrawEx(int nImage, HDC hDC, int x, int y, int dx, int dy, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_DrawEx(m_hImageList, nImage, hDC, x, y, dx, dy, rgbBk, rgbFg, fStyle); + } + + BOOL DrawEx(int nImage, HDC hDC, RECT& rect, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_DrawEx(m_hImageList, nImage, hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, rgbBk, rgbFg, fStyle); + } + + static BOOL DrawIndirect(IMAGELISTDRAWPARAMS* pimldp) + { + return ImageList_DrawIndirect(pimldp); + } + + BOOL Copy(int nSrc, int nDst, UINT uFlags = ILCF_MOVE) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Copy(m_hImageList, nDst, m_hImageList, nSrc, uFlags); + } + +#ifdef __IStream_INTERFACE_DEFINED__ +#ifndef _WIN32_WCE + static HIMAGELIST Read(LPSTREAM lpStream) + { + return ImageList_Read(lpStream); + } + + BOOL Write(LPSTREAM lpStream) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Write(m_hImageList, lpStream); + } +#endif // !_WIN32_WCE + +#if (_WIN32_WINNT >= 0x0501) + static HRESULT ReadEx(DWORD dwFlags, LPSTREAM lpStream, REFIID riid, PVOID* ppv) + { + return ImageList_ReadEx(dwFlags, lpStream, riid, ppv); + } + + HRESULT WriteEx(DWORD dwFlags, LPSTREAM lpStream) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_WriteEx(m_hImageList, dwFlags, lpStream); + } +#endif // (_WIN32_WINNT >= 0x0501) +#endif // __IStream_INTERFACE_DEFINED__ + + // Drag operations + BOOL BeginDrag(int nImage, POINT ptHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_BeginDrag(m_hImageList, nImage, ptHotSpot.x, ptHotSpot.y); + } + + BOOL BeginDrag(int nImage, int xHotSpot, int yHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_BeginDrag(m_hImageList, nImage, xHotSpot, yHotSpot); + } + + static void EndDrag() + { + ImageList_EndDrag(); + } + + static BOOL DragMove(POINT pt) + { + return ImageList_DragMove(pt.x, pt.y); + } + + static BOOL DragMove(int x, int y) + { + return ImageList_DragMove(x, y); + } + + BOOL SetDragCursorImage(int nDrag, POINT ptHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetDragCursorImage(m_hImageList, nDrag, ptHotSpot.x, ptHotSpot.y); + } + + BOOL SetDragCursorImage(int nDrag, int xHotSpot, int yHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetDragCursorImage(m_hImageList, nDrag, xHotSpot, yHotSpot); + } + + static BOOL DragShowNolock(BOOL bShow = TRUE) + { + return ImageList_DragShowNolock(bShow); + } + + static CImageList GetDragImage(LPPOINT lpPoint, LPPOINT lpPointHotSpot) + { + return CImageList(ImageList_GetDragImage(lpPoint, lpPointHotSpot)); + } + + static BOOL DragEnter(HWND hWnd, POINT point) + { + return ImageList_DragEnter(hWnd, point.x, point.y); + } + + static BOOL DragEnter(HWND hWnd, int x, int y) + { + return ImageList_DragEnter(hWnd, x, y); + } + + static BOOL DragLeave(HWND hWnd) + { + return ImageList_DragLeave(hWnd); + } + +#if (_WIN32_IE >= 0x0400) + CImageList Duplicate() const + { + ATLASSERT(m_hImageList != NULL); + return CImageList(ImageList_Duplicate(m_hImageList)); + } + + static CImageList Duplicate(HIMAGELIST hImageList) + { + ATLASSERT(hImageList != NULL); + return CImageList(ImageList_Duplicate(hImageList)); + } +#endif // (_WIN32_IE >= 0x0400) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CToolTipCtrl + +#ifndef _WIN32_WCE + +class CToolInfo : public TOOLINFO +{ +public: + CToolInfo(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL) + { + Init(nFlags, hWnd, nIDTool, lpRect, lpstrText, lUserParam); + } + + operator LPTOOLINFO() { return this; } + + operator LPARAM() { return (LPARAM)this; } + + void Init(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL) + { + ATLASSERT(::IsWindow(hWnd)); + memset(this, 0, sizeof(TOOLINFO)); + cbSize = sizeof(TOOLINFO); + uFlags = nFlags; + if(nIDTool == 0) + { + hwnd = ::GetParent(hWnd); + uFlags |= TTF_IDISHWND; + uId = (UINT_PTR)hWnd; + } + else + { + hwnd = hWnd; + uId = nIDTool; + } + if(lpRect != NULL) + rect = *lpRect; + hinst = ModuleHelper::GetResourceInstance(); + lpszText = lpstrText; + lParam = lUserParam; + } +}; + +template +class CToolTipCtrlT : public TBase +{ +public: +// Constructors + CToolTipCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CToolTipCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return TOOLTIPS_CLASS; + } + + void GetText(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_GETTEXT, 0, (LPARAM)&lpToolInfo); + } + + void GetText(LPTSTR lpstrText, HWND hWnd, UINT nIDTool = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText); + ::SendMessage(m_hWnd, TTM_GETTEXT, 0, ti); + } + + BOOL GetToolInfo(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, (LPARAM)lpToolInfo); + } + + BOOL GetToolInfo(HWND hWnd, UINT nIDTool, UINT* puFlags, LPRECT lpRect, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + ATLASSERT(puFlags != NULL); + ATLASSERT(lpRect != NULL); + CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText); + BOOL bRet = (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, ti); + if(bRet != FALSE) + { + *puFlags = ti.uFlags; + *lpRect = ti.rect; + } + return bRet; + } + + void SetToolInfo(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETTOOLINFO, 0, (LPARAM)lpToolInfo); + } + + void SetToolRect(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, (LPARAM)lpToolInfo); + } + + void SetToolRect(HWND hWnd, UINT nIDTool, LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + ATLASSERT(nIDTool != 0); + + CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRect, NULL); + ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, ti); + } + + int GetToolCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_GETTOOLCOUNT, 0, 0L); + } + + int GetDelayTime(DWORD dwType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_GETDELAYTIME, dwType, 0L); + } + + void SetDelayTime(DWORD dwType, int nTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETDELAYTIME, dwType, MAKELPARAM(nTime, 0)); + } + + void GetMargin(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_GETMARGIN, 0, (LPARAM)lpRect); + } + + void SetMargin(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)lpRect); + } + + int GetMaxTipWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_GETMAXTIPWIDTH, 0, 0L); + } + + int SetMaxTipWidth(int nWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_SETMAXTIPWIDTH, 0, nWidth); + } + + COLORREF GetTipBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPBKCOLOR, 0, 0L); + } + + void SetTipBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETTIPBKCOLOR, (WPARAM)clr, 0L); + } + + COLORREF GetTipTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPTEXTCOLOR, 0, 0L); + } + + void SetTipTextColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETTIPTEXTCOLOR, (WPARAM)clr, 0L); + } + + BOOL GetCurrentTool(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_GETCURRENTTOOL, 0, (LPARAM)lpToolInfo); + } + +#if (_WIN32_IE >= 0x0500) + SIZE GetBubbleSize(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TTM_GETBUBBLESIZE, 0, (LPARAM)lpToolInfo); + SIZE size = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) }; + return size; + } + + BOOL SetTitle(UINT uIcon, LPCTSTR lpstrTitle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_SETTITLE, uIcon, (LPARAM)lpstrTitle); + } +#endif // (_WIN32_IE >= 0x0500) + +#if (_WIN32_WINNT >= 0x0501) + void GetTitle(PTTGETTITLE pTTGetTitle) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_GETTITLE, 0, (LPARAM)pTTGetTitle); + } + + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + void Activate(BOOL bActivate) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_ACTIVATE, bActivate, 0L); + } + + BOOL AddTool(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, (LPARAM)lpToolInfo); + } + + BOOL AddTool(HWND hWnd, ATL::_U_STRINGorID text = LPSTR_TEXTCALLBACK, LPCRECT lpRectTool = NULL, UINT nIDTool = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + // the toolrect and toolid must both be zero or both valid + ATLASSERT((lpRectTool != NULL && nIDTool != 0) || (lpRectTool == NULL && nIDTool == 0)); + + CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRectTool, (LPTSTR)text.m_lpstr); + return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, ti); + } + + void DelTool(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_DELTOOL, 0, (LPARAM)lpToolInfo); + } + + void DelTool(HWND hWnd, UINT nIDTool = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + + CToolInfo ti(0, hWnd, nIDTool, NULL, NULL); + ::SendMessage(m_hWnd, TTM_DELTOOL, 0, ti); + } + + BOOL HitTest(LPTTHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)lpHitTestInfo); + } + + BOOL HitTest(HWND hWnd, POINT pt, LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + ATLASSERT(lpToolInfo != NULL); + + TTHITTESTINFO hti = { 0 }; + hti.ti.cbSize = sizeof(TOOLINFO); + hti.hwnd = hWnd; + hti.pt.x = pt.x; + hti.pt.y = pt.y; + if((BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)&hti) != FALSE) + { + *lpToolInfo = hti.ti; + return TRUE; + } + return FALSE; + } + + void RelayEvent(LPMSG lpMsg) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_RELAYEVENT, 0, (LPARAM)lpMsg); + } + + void UpdateTipText(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)lpToolInfo); + } + + void UpdateTipText(ATL::_U_STRINGorID text, HWND hWnd, UINT nIDTool = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + + CToolInfo ti(0, hWnd, nIDTool, NULL, (LPTSTR)text.m_lpstr); + ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, ti); + } + + BOOL EnumTools(UINT nTool, LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_ENUMTOOLS, nTool, (LPARAM)lpToolInfo); + } + + void Pop() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_POP, 0, 0L); + } + + void TrackActivate(LPTOOLINFO lpToolInfo, BOOL bActivate) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_TRACKACTIVATE, bActivate, (LPARAM)lpToolInfo); + } + + void TrackPosition(int xPos, int yPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_TRACKPOSITION, 0, MAKELPARAM(xPos, yPos)); + } + +#if (_WIN32_IE >= 0x0400) + void Update() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_UPDATE, 0, 0L); + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) + BOOL AdjustRect(LPRECT lpRect, BOOL bLarger /*= TRUE*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_ADJUSTRECT, bLarger, (LPARAM)lpRect); + } +#endif // (_WIN32_IE >= 0x0500) + +#if (_WIN32_WINNT >= 0x0501) + void Popup() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_POPUP, 0, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) +}; + +typedef CToolTipCtrlT CToolTipCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CHeaderCtrl + +template +class CHeaderCtrlT : public TBase +{ +public: +// Constructors + CHeaderCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CHeaderCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_HEADER; + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_GETITEMCOUNT, 0, 0L); + } + + BOOL GetItem(int nIndex, LPHDITEM pHeaderItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETITEM, nIndex, (LPARAM)pHeaderItem); + } + + BOOL SetItem(int nIndex, LPHDITEM pHeaderItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETITEM, nIndex, (LPARAM)pHeaderItem); + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_GETIMAGELIST, 0, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_SETIMAGELIST, 0, (LPARAM)hImageList)); + } + + BOOL GetOrderArray(int nSize, int* lpnArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETORDERARRAY, nSize, (LPARAM)lpnArray); + } + + BOOL SetOrderArray(int nSize, int* lpnArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETORDERARRAY, nSize, (LPARAM)lpnArray); + } + + BOOL GetItemRect(int nIndex, LPRECT lpItemRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMRECT, nIndex, (LPARAM)lpItemRect); + } + + int SetHotDivider(BOOL bPos, DWORD dwInputValue) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_SETHOTDIVIDER, bPos, dwInputValue); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int GetBitmapMargin() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_GETBITMAPMARGIN, 0, 0L); + } + + int SetBitmapMargin(int nWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_SETBITMAPMARGIN, nWidth, 0L); + } + + int SetFilterChangeTimeout(DWORD dwTimeOut) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_SETFILTERCHANGETIMEOUT, 0, dwTimeOut); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0600) + BOOL GetItemDropDownRect(int nIndex, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMDROPDOWNRECT, nIndex, (LPARAM)lpRect); + } + + BOOL GetOverflowRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETOVERFLOWRECT, 0, (LPARAM)lpRect); + } + + int GetFocusedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_GETFOCUSEDITEM, 0, 0L); + } + + BOOL SetFocusedItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETFOCUSEDITEM, 0, nIndex); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + int InsertItem(int nIndex, LPHDITEM phdi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_INSERTITEM, nIndex, (LPARAM)phdi); + } + + int AddItem(LPHDITEM phdi) + { + return InsertItem(GetItemCount(), phdi); + } + + BOOL DeleteItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_DELETEITEM, nIndex, 0L); + } + + BOOL Layout(HD_LAYOUT* pHeaderLayout) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_LAYOUT, 0, (LPARAM)pHeaderLayout); + } + + int HitTest(LPHDHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_HITTEST, 0, (LPARAM)lpHitTestInfo); + } + + int OrderToIndex(int nOrder) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_ORDERTOINDEX, nOrder, 0L); + } + + CImageList CreateDragImage(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_CREATEDRAGIMAGE, nIndex, 0L)); + } + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int EditFilter(int nColumn, BOOL bDiscardChanges) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_EDITFILTER, nColumn, MAKELPARAM(bDiscardChanges, 0)); + } + + int ClearFilter(int nColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, nColumn, 0L); + } + + int ClearAllFilters() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, (WPARAM)-1, 0L); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CHeaderCtrlT CHeaderCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CListViewCtrl + +template +class CListViewCtrlT : public TBase +{ +public: +// Constructors + CListViewCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CListViewCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_LISTVIEW; + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETBKCOLOR, 0, 0L); + } + + BOOL SetBkColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETBKCOLOR, 0, cr); + } + + CImageList GetImageList(int nImageListType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_GETIMAGELIST, nImageListType, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList, int nImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, nImageList, (LPARAM)hImageList)); + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETITEMCOUNT, 0, 0L); + } + + BOOL SetItemCount(int nItems) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, 0L); + } + + BOOL GetItem(LPLVITEM pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(const LVITEM* pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem, + int nImage, UINT nState, UINT nStateMask, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.mask = nMask; + lvi.iItem = nItem; + lvi.iSubItem = nSubItem; + lvi.stateMask = nStateMask; + lvi.state = nState; + lvi.pszText = (LPTSTR) lpszItem; + lvi.iImage = nImage; + lvi.lParam = lParam; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)&lvi); + } + + UINT GetItemState(int nItem, UINT nMask) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETITEMSTATE, nItem, nMask); + } + + BOOL SetItemState(int nItem, UINT nState, UINT nStateMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.state = nState; + lvi.stateMask = nStateMask; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)&lvi); + } + + BOOL SetItemState(int nItem, LPLVITEM pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)pItem); + } + +#ifndef _ATL_NO_COM + BOOL GetItemText(int nItem, int nSubItem, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + LVITEM lvi = { 0 }; + lvi.iSubItem = nSubItem; + + LPTSTR lpstrText = NULL; + int nRes = 0; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + lpstrText[0] = NULL; + lvi.cchTextMax = nLen; + lvi.pszText = lpstrText; + nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); + if(nRes < nLen - 1) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(nRes != 0) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetItemText(int nItem, int nSubItem, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.iSubItem = nSubItem; + + strText.Empty(); + int nRes = 0; + for(int nLen = 256; ; nLen *= 2) + { + lvi.cchTextMax = nLen; + lvi.pszText = strText.GetBufferSetLength(nLen); + if(lvi.pszText == NULL) + { + nRes = 0; + break; + } + nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); + if(nRes < nLen - 1) + break; + } + strText.ReleaseBuffer(); + return nRes; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + int GetItemText(int nItem, int nSubItem, LPTSTR lpszText, int nLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.iSubItem = nSubItem; + lvi.cchTextMax = nLen; + lvi.pszText = lpszText; + return (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); + } + + BOOL SetItemText(int nItem, int nSubItem, LPCTSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(nItem, nSubItem, LVIF_TEXT, lpszText, 0, 0, 0, 0); + } + + DWORD_PTR GetItemData(int nItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.iItem = nItem; + lvi.mask = LVIF_PARAM; + BOOL bRet = (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi); + return (DWORD_PTR)(bRet ? lvi.lParam : NULL); + } + + BOOL SetItemData(int nItem, DWORD_PTR dwData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(nItem, 0, LVIF_PARAM, NULL, 0, 0, 0, (LPARAM)dwData); + } + + UINT GetCallbackMask() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETCALLBACKMASK, 0, 0L); + } + + BOOL SetCallbackMask(UINT nMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCALLBACKMASK, nMask, 0L); + } + + BOOL GetItemPosition(int nItem, LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMPOSITION, nItem, (LPARAM)lpPoint); + } + + BOOL SetItemPosition(int nItem, POINT pt) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt); + } + + BOOL SetItemPosition(int nItem, int x, int y) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON)); + POINT pt = { x, y }; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt); + } + + int GetStringWidth(LPCTSTR lpsz) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETSTRINGWIDTH, 0, (LPARAM)lpsz); + } + + CEdit GetEditControl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, LVM_GETEDITCONTROL, 0, 0L)); + } + + BOOL GetColumn(int nCol, LVCOLUMN* pColumn) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMN, nCol, (LPARAM)pColumn); + } + + BOOL SetColumn(int nCol, const LVCOLUMN* pColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMN, nCol, (LPARAM)pColumn); + } + + int GetColumnWidth(int nCol) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETCOLUMNWIDTH, nCol, 0L); + } + + BOOL SetColumnWidth(int nCol, int cx) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNWIDTH, nCol, MAKELPARAM(cx, 0)); + } + + BOOL GetViewRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETVIEWRECT, 0, (LPARAM)lpRect); + } + + COLORREF GetTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTCOLOR, 0, 0L); + } + + BOOL SetTextColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTCOLOR, 0, cr); + } + + COLORREF GetTextBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTBKCOLOR, 0, 0L); + } + + BOOL SetTextBkColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTBKCOLOR, 0, cr); + } + + int GetTopIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETTOPINDEX, 0, 0L); + } + + int GetCountPerPage() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETCOUNTPERPAGE, 0, 0L); + } + + BOOL GetOrigin(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETORIGIN, 0, (LPARAM)lpPoint); + } + + UINT GetSelectedCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETSELECTEDCOUNT, 0, 0L); + } + + BOOL GetItemRect(int nItem, LPRECT lpRect, UINT nCode) const + { + ATLASSERT(::IsWindow(m_hWnd)); + lpRect->left = nCode; + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMRECT, (WPARAM)nItem, (LPARAM)lpRect); + } + +#ifndef _WIN32_WCE + HCURSOR GetHotCursor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, LVM_GETHOTCURSOR, 0, 0L); + } + + HCURSOR SetHotCursor(HCURSOR hHotCursor) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, LVM_SETHOTCURSOR, 0, (LPARAM)hHotCursor); + } + + int GetHotItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETHOTITEM, 0, 0L); + } + + int SetHotItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETHOTITEM, nIndex, 0L); + } +#endif // !_WIN32_WCE + + BOOL GetColumnOrderArray(int nCount, int* lpnArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray); + } + + BOOL SetColumnOrderArray(int nCount, int* lpnArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray); + } + + CHeaderCtrl GetHeader() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CHeaderCtrl((HWND)::SendMessage(m_hWnd, LVM_GETHEADER, 0, 0L)); + } + + BOOL GetSubItemRect(int nItem, int nSubItem, int nFlag, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_REPORT); + ATLASSERT(lpRect != NULL); + lpRect->top = nSubItem; + lpRect->left = nFlag; + return (BOOL)::SendMessage(m_hWnd, LVM_GETSUBITEMRECT, nItem, (LPARAM)lpRect); + } + + DWORD SetIconSpacing(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_ICON); + return (DWORD)::SendMessage(m_hWnd, LVM_SETICONSPACING, 0, MAKELPARAM(cx, cy)); + } + + int GetISearchString(LPTSTR lpstr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETISEARCHSTRING, 0, (LPARAM)lpstr); + } + + void GetItemSpacing(SIZE& sizeSpacing, BOOL bSmallIconView = FALSE) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, LVM_GETITEMSPACING, bSmallIconView, 0L); + sizeSpacing.cx = GET_X_LPARAM(dwRet); + sizeSpacing.cy = GET_Y_LPARAM(dwRet); + } + +#if (_WIN32_WCE >= 410) + void SetItemSpacing(INT cySpacing) + { + ATLASSERT(::IsWindow(m_hWnd)); + ListView_SetItemSpacing(m_hWnd, cySpacing); + } +#endif // (_WIN32_WCE >= 410) + + // single-selection only + int GetSelectedIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); + return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); + } + + BOOL GetSelectedItem(LPLVITEM pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); + ATLASSERT(pItem != NULL); + pItem->iItem = (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); + if(pItem->iItem == -1) + return FALSE; + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem); + } + + // extended list view styles + DWORD GetExtendedListViewStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L); + } + + // dwExMask = 0 means all styles + DWORD SetExtendedListViewStyle(DWORD dwExStyle, DWORD dwExMask = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, dwExMask, dwExStyle); + } + + // checkboxes only + BOOL GetCheckState(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetExtendedListViewStyle() & LVS_EX_CHECKBOXES) != 0); + UINT uRet = GetItemState(nIndex, LVIS_STATEIMAGEMASK); + return (uRet >> 12) - 1; + } + + BOOL SetCheckState(int nItem, BOOL bCheck) + { + int nCheck = bCheck ? 2 : 1; // one based index + return SetItemState(nItem, INDEXTOSTATEIMAGEMASK(nCheck), LVIS_STATEIMAGEMASK); + } + + // view type + DWORD GetViewType() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (GetStyle() & LVS_TYPEMASK); + } + + DWORD SetViewType(DWORD dwType) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(dwType == LVS_ICON || dwType == LVS_SMALLICON || dwType == LVS_LIST || dwType == LVS_REPORT); + DWORD dwOldType = GetViewType(); + if(dwType != dwOldType) + ModifyStyle(LVS_TYPEMASK, (dwType & LVS_TYPEMASK)); + return dwOldType; + } + +#if (_WIN32_IE >= 0x0400) +#ifndef _WIN32_WCE + BOOL GetBkImage(LPLVBKIMAGE plvbki) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETBKIMAGE, 0, (LPARAM)plvbki); + } + + BOOL SetBkImage(LPLVBKIMAGE plvbki) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETBKIMAGE, 0, (LPARAM)plvbki); + } +#endif // !_WIN32_WCE + + int GetSelectionMark() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETSELECTIONMARK, 0, 0L); + } + + int SetSelectionMark(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETSELECTIONMARK, 0, nIndex); + } + +#ifndef _WIN32_WCE + BOOL GetWorkAreas(int nWorkAreas, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETWORKAREAS, nWorkAreas, (LPARAM)lpRect); + } + + BOOL SetWorkAreas(int nWorkAreas, LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETWORKAREAS, nWorkAreas, (LPARAM)lpRect); + } + + DWORD GetHoverTime() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0); + return (DWORD)::SendMessage(m_hWnd, LVM_GETHOVERTIME, 0, 0L); + } + + DWORD SetHoverTime(DWORD dwHoverTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0); + return (DWORD)::SendMessage(m_hWnd, LVM_SETHOVERTIME, 0, dwHoverTime); + } + + BOOL GetNumberOfWorkAreas(int* pnWorkAreas) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETNUMBEROFWORKAREAS, 0, (LPARAM)pnWorkAreas); + } +#endif // !_WIN32_WCE + + BOOL SetItemCountEx(int nItems, DWORD dwFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LVS_OWNERDATA) != 0) && (((GetStyle() & LVS_TYPEMASK) == LVS_REPORT) || ((GetStyle() & LVS_TYPEMASK) == LVS_LIST))); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, dwFlags); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_GETTOOLTIPS, 0, 0L)); + } + + CToolTipCtrl SetToolTips(HWND hWndTT) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L)); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0501) + int GetSelectedColumn() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETSELECTEDCOLUMN, 0, 0L); + } + + void SetSelectedColumn(int nColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_SETSELECTEDCOLUMN, nColumn, 0L); + } + + DWORD GetView() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_GETVIEW, 0, 0L); + } + + int SetView(DWORD dwView) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETVIEW, dwView, 0L); + } + + BOOL IsGroupViewEnabled() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_ISGROUPVIEWENABLED, 0, 0L); + } + + int GetGroupInfo(int nGroupID, PLVGROUP pGroup) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETGROUPINFO, nGroupID, (LPARAM)pGroup); + } + + int SetGroupInfo(int nGroupID, PLVGROUP pGroup) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETGROUPINFO, nGroupID, (LPARAM)pGroup); + } + + void GetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_GETGROUPMETRICS, 0, (LPARAM)pGroupMetrics); + } + + void SetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_SETGROUPMETRICS, 0, (LPARAM)pGroupMetrics); + } + + void GetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_GETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo); + } + + BOOL SetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo); + } + + void GetTileInfo(PLVTILEINFO pTileInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_GETTILEINFO, 0, (LPARAM)pTileInfo); + } + + BOOL SetTileInfo(PLVTILEINFO pTileInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEINFO, 0, (LPARAM)pTileInfo); + } + + BOOL GetInsertMark(LPLVINSERTMARK pInsertMark) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETINSERTMARK, 0, (LPARAM)pInsertMark); + } + + BOOL SetInsertMark(LPLVINSERTMARK pInsertMark) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETINSERTMARK, 0, (LPARAM)pInsertMark); + } + + int GetInsertMarkRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETINSERTMARKRECT, 0, (LPARAM)lpRect); + } + + COLORREF GetInsertMarkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETINSERTMARKCOLOR, 0, 0L); + } + + COLORREF SetInsertMarkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_SETINSERTMARKCOLOR, 0, clr); + } + + COLORREF GetOutlineColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETOUTLINECOLOR, 0, 0L); + } + + COLORREF SetOutlineColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_SETOUTLINECOLOR, 0, clr); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + int GetGroupCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETGROUPCOUNT, 0, 0L); + } + + BOOL GetGroupInfoByIndex(int nIndex, PLVGROUP pGroup) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPINFOBYINDEX, nIndex, (LPARAM)pGroup); + } + + BOOL GetGroupRect(int nGroupID, int nType, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpRect != NULL); + if(lpRect != NULL) + lpRect->top = nType; + return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPRECT, nGroupID, (LPARAM)lpRect); + } + + UINT GetGroupState(int nGroupID, UINT uMask) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETGROUPSTATE, nGroupID, (LPARAM)uMask); + } + + int GetFocusedGroup() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETFOCUSEDGROUP, 0, 0L); + } + + BOOL GetEmptyText(LPWSTR lpstrText, int cchText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETEMPTYTEXT, cchText, (LPARAM)lpstrText); + } + + BOOL GetFooterRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERRECT, 0, (LPARAM)lpRect); + } + + BOOL GetFooterInfo(LPLVFOOTERINFO lpFooterInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERINFO, 0, (LPARAM)lpFooterInfo); + } + + BOOL GetFooterItemRect(int nItem, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEMRECT, nItem, (LPARAM)lpRect); + } + + BOOL GetFooterItem(int nItem, LPLVFOOTERITEM lpFooterItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEM, nItem, (LPARAM)lpFooterItem); + } + + BOOL GetItemIndexRect(PLVITEMINDEX pItemIndex, int nSubItem, int nType, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pItemIndex != NULL); + ATLASSERT(lpRect != NULL); + if(lpRect != NULL) + { + lpRect->top = nSubItem; + lpRect->left = nType; + } + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMINDEXRECT, (WPARAM)pItemIndex, (LPARAM)lpRect); + } + + BOOL SetItemIndexState(PLVITEMINDEX pItemIndex, UINT uState, UINT dwMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.state = uState; + lvi.stateMask = dwMask; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMINDEXSTATE, (WPARAM)pItemIndex, (LPARAM)&lvi); + } + + BOOL GetNextItemIndex(PLVITEMINDEX pItemIndex, WORD wFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETNEXTITEMINDEX, (WPARAM)pItemIndex, MAKELPARAM(wFlags, 0)); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + int InsertColumn(int nCol, const LVCOLUMN* pColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_INSERTCOLUMN, nCol, (LPARAM)pColumn); + } + + int InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat = LVCFMT_LEFT, + int nWidth = -1, int nSubItem = -1, int iImage = -1, int iOrder = -1) + { + LVCOLUMN column = { 0 }; + column.mask = LVCF_TEXT|LVCF_FMT; + column.pszText = (LPTSTR)lpszColumnHeading; + column.fmt = nFormat; + if (nWidth != -1) + { + column.mask |= LVCF_WIDTH; + column.cx = nWidth; + } + if (nSubItem != -1) + { + column.mask |= LVCF_SUBITEM; + column.iSubItem = nSubItem; + } + if (iImage != -1) + { + column.mask |= LVCF_IMAGE; + column.iImage = iImage; + } + if (iOrder != -1) + { + column.mask |= LVCF_ORDER; + column.iOrder = iOrder; + } + return InsertColumn(nCol, &column); + } + + BOOL DeleteColumn(int nCol) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_DELETECOLUMN, nCol, 0L); + } + + int InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM item = { 0 }; + item.mask = nMask; + item.iItem = nItem; + item.iSubItem = 0; + item.pszText = (LPTSTR)lpszItem; + item.state = nState; + item.stateMask = nStateMask; + item.iImage = nImage; + item.lParam = lParam; + return InsertItem(&item); + } + + int InsertItem(const LVITEM* pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)pItem); + } + + int InsertItem(int nItem, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(LVIF_TEXT, nItem, lpszItem, 0, 0, 0, 0); + } + + int InsertItem(int nItem, LPCTSTR lpszItem, int nImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(LVIF_TEXT|LVIF_IMAGE, nItem, lpszItem, 0, 0, nImage, 0); + } + + int GetNextItem(int nItem, int nFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, nItem, MAKELPARAM(nFlags, 0)); + } + + BOOL DeleteItem(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_DELETEITEM, nItem, 0L); + } + + BOOL DeleteAllItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_DELETEALLITEMS, 0, 0L); + } + + int FindItem(LVFINDINFO* pFindInfo, int nStart) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_FINDITEM, nStart, (LPARAM)pFindInfo); + } + + int HitTest(LVHITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)pHitTestInfo); + } + + int HitTest(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVHITTESTINFO hti = { 0 }; + hti.pt = pt; + int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return nRes; + } + + BOOL EnsureVisible(int nItem, BOOL bPartialOK) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_ENSUREVISIBLE, nItem, MAKELPARAM(bPartialOK, 0)); + } + + BOOL Scroll(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SCROLL, size.cx, size.cy); + } + + BOOL RedrawItems(int nFirst, int nLast) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_REDRAWITEMS, nFirst, nLast); + } + + BOOL Arrange(UINT nCode) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_ARRANGE, nCode, 0L); + } + + CEdit EditLabel(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, LVM_EDITLABEL, nItem, 0L)); + } + + BOOL Update(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_UPDATE, nItem, 0L); + } + + BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMS, (WPARAM)lParamSort, (LPARAM)pfnCompare); + } + + CImageList RemoveImageList(int nImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, (WPARAM)nImageList, NULL)); + } + + CImageList CreateDragImage(int nItem, LPPOINT lpPoint) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint)); + } + + DWORD ApproximateViewRect(int cx = -1, int cy = -1, int nCount = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_APPROXIMATEVIEWRECT, nCount, MAKELPARAM(cx, cy)); + } + + int SubItemHitTest(LPLVHITTESTINFO lpInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, 0, (LPARAM)lpInfo); + } + + int AddColumn(LPCTSTR strItem, int nItem, int nSubItem = -1, + int nMask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM, + int nFmt = LVCFMT_LEFT) + { + const int cxOffset = 15; + ATLASSERT(::IsWindow(m_hWnd)); + LVCOLUMN lvc = { 0 }; + lvc.mask = nMask; + lvc.fmt = nFmt; + lvc.pszText = (LPTSTR)strItem; + lvc.cx = GetStringWidth(lvc.pszText) + cxOffset; + if(nMask & LVCF_SUBITEM) + lvc.iSubItem = (nSubItem != -1) ? nSubItem : nItem; + return InsertColumn(nItem, &lvc); + } + + int AddItem(int nItem, int nSubItem, LPCTSTR strItem, int nImageIndex = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvItem = { 0 }; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = nItem; + lvItem.iSubItem = nSubItem; + lvItem.pszText = (LPTSTR)strItem; + if(nImageIndex != -1) + { + lvItem.mask |= LVIF_IMAGE; + lvItem.iImage = nImageIndex; + } + if(nSubItem == 0) + return InsertItem(&lvItem); + return SetItem(&lvItem) ? nItem : -1; + } + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + BOOL SortItemsEx(PFNLVCOMPARE pfnCompare, LPARAM lParamSort) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMSEX, (WPARAM)lParamSort, (LPARAM)pfnCompare); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + int InsertGroup(int nItem, PLVGROUP pGroup) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_INSERTGROUP, nItem, (LPARAM)pGroup); + } + + int AddGroup(PLVGROUP pGroup) + { + return InsertGroup(-1, pGroup); + } + + int RemoveGroup(int nGroupID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_REMOVEGROUP, nGroupID, 0L); + } + + void MoveGroup(int nGroupID, int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_MOVEGROUP, nGroupID, nItem); + } + + void MoveItemToGroup(int nItem, int nGroupID) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_MOVEITEMTOGROUP, nItem, nGroupID); + } + + int EnableGroupView(BOOL bEnable) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_ENABLEGROUPVIEW, bEnable, 0L); + } + + int SortGroups(PFNLVGROUPCOMPARE pCompareFunc, LPVOID lpVoid = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SORTGROUPS, (WPARAM)pCompareFunc, (LPARAM)lpVoid); + } + + void InsertGroupSorted(PLVINSERTGROUPSORTED pInsertGroupSorted) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_INSERTGROUPSORTED, (WPARAM)pInsertGroupSorted, 0L); + } + + void RemoveAllGroups() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_REMOVEALLGROUPS, 0, 0L); + } + + BOOL HasGroup(int nGroupID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_HASGROUP, nGroupID, 0L); + } + + BOOL InsertMarkHitTest(LPPOINT lpPoint, LPLVINSERTMARK pInsertMark) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)pInsertMark); + } + + BOOL SetInfoTip(PLVSETINFOTIP pSetInfoTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETINFOTIP, 0, (LPARAM)pSetInfoTip); + } + + void CancelEditLabel() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_CANCELEDITLABEL, 0, 0L); + } + + UINT MapIndexToID(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_MAPINDEXTOID, nIndex, 0L); + } + + int MapIDToIndex(UINT uID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_MAPIDTOINDEX, uID, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + int HitTestEx(LPLVHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo); + } + + int HitTestEx(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVHITTESTINFO hti = { 0 }; + hti.pt = pt; + int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return nRes; + } + + int SubItemHitTestEx(LPLVHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo); + } +#endif // (_WIN32_WINNT >= 0x0600) + + // single-selection only + BOOL SelectItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); + + BOOL bRet = SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + if(bRet) + bRet = EnsureVisible(nIndex, FALSE); + return bRet; + } +}; + +typedef CListViewCtrlT CListViewCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTreeViewCtrl + +template +class CTreeViewCtrlT : public TBase +{ +public: +// Constructors + CTreeViewCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTreeViewCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_TREEVIEW; + } + + UINT GetCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_GETCOUNT, 0, 0L); + } + + UINT GetIndent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_GETINDENT, 0, 0L); + } + + void SetIndent(UINT nIndent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TVM_SETINDENT, nIndent, 0L); + } + + CImageList GetImageList(int nImageListType = TVSIL_NORMAL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_GETIMAGELIST, (WPARAM)nImageListType, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList, int nImageListType = TVSIL_NORMAL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageListType, (LPARAM)hImageList)); + } + + BOOL GetItem(LPTVITEM pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(LPTVITEM pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = nMask; + item.pszText = (LPTSTR) lpszItem; + item.iImage = nImage; + item.iSelectedImage = nSelectedImage; + item.state = nState; + item.stateMask = nStateMask; + item.lParam = lParam; + return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item); + } + + BOOL GetItemText(HTREEITEM hItem, LPTSTR lpstrText, int nLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpstrText != NULL); + + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_TEXT; + item.pszText = lpstrText; + item.cchTextMax = nLen; + + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + } + +#ifndef _ATL_NO_COM + BOOL GetItemText(HTREEITEM hItem, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_TEXT; + + LPTSTR lpstrText = NULL; + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + lpstrText[0] = NULL; + item.pszText = lpstrText; + item.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + if(!bRet || (lstrlen(item.pszText) < nLen - 1)) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(bRet) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetItemText(HTREEITEM hItem, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_TEXT; + + strText.Empty(); + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + item.pszText = strText.GetBufferSetLength(nLen); + if(item.pszText == NULL) + { + bRet = FALSE; + break; + } + item.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + if(!bRet || (lstrlen(item.pszText) < nLen - 1)) + break; + } + strText.ReleaseBuffer(); + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL SetItemText(HTREEITEM hItem, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_TEXT, lpszItem, 0, 0, 0, 0, NULL); + } + + BOOL GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE; + BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + if (bRes) + { + nImage = item.iImage; + nSelectedImage = item.iSelectedImage; + } + return bRes; + } + + BOOL SetItemImage(HTREEITEM hItem, int nImage, int nSelectedImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_IMAGE|TVIF_SELECTEDIMAGE, NULL, nImage, nSelectedImage, 0, 0, NULL); + } + + UINT GetItemState(HTREEITEM hItem, UINT nStateMask) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + return (((UINT)::SendMessage(m_hWnd, TVM_GETITEMSTATE, (WPARAM)hItem, (LPARAM)nStateMask)) & nStateMask); +#else // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)) + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_STATE; + item.state = 0; + item.stateMask = nStateMask; + ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + return (item.state & nStateMask); +#endif // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)) + } + + BOOL SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_STATE, NULL, 0, 0, nState, nStateMask, NULL); + } + + DWORD_PTR GetItemData(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_PARAM; + BOOL bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + return (DWORD_PTR)(bRet ? item.lParam : NULL); + } + + BOOL SetItemData(HTREEITEM hItem, DWORD_PTR dwData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData); + } + + CEdit GetEditControl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, TVM_GETEDITCONTROL, 0, 0L)); + } + + UINT GetVisibleCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_GETVISIBLECOUNT, 0, 0L); + } + + BOOL GetItemRect(HTREEITEM hItem, LPRECT lpRect, BOOL bTextOnly) const + { + ATLASSERT(::IsWindow(m_hWnd)); + *(HTREEITEM*)lpRect = hItem; + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMRECT, (WPARAM)bTextOnly, (LPARAM)lpRect); + } + + BOOL ItemHasChildren(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_CHILDREN; + ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + return item.cChildren; + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_GETTOOLTIPS, 0, 0L)); + } + + CToolTipCtrl SetToolTips(HWND hWndTT) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L)); + } +#endif // !_WIN32_WCE + + int GetISearchString(LPTSTR lpstr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_GETISEARCHSTRING, 0, (LPARAM)lpstr); + } + + // checkboxes only + BOOL GetCheckState(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & TVS_CHECKBOXES) != 0); + UINT uRet = GetItemState(hItem, TVIS_STATEIMAGEMASK); + return (uRet >> 12) - 1; + } + + BOOL SetCheckState(HTREEITEM hItem, BOOL bCheck) + { + int nCheck = bCheck ? 2 : 1; // one based index + return SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nCheck), TVIS_STATEIMAGEMASK); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETBKCOLOR, 0, 0L); + } + + COLORREF SetBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETBKCOLOR, 0, (LPARAM)clr); + } + + COLORREF GetInsertMarkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETINSERTMARKCOLOR, 0, 0L); + } + + COLORREF SetInsertMarkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETINSERTMARKCOLOR, 0, (LPARAM)clr); + } + + int GetItemHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_GETITEMHEIGHT, 0, 0L); + } + + int SetItemHeight(int cyHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_SETITEMHEIGHT, cyHeight, 0L); + } + + int GetScrollTime() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_GETSCROLLTIME, 0, 0L); + } + + int SetScrollTime(int nScrollTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_SETSCROLLTIME, nScrollTime, 0L); + } + + COLORREF GetTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETTEXTCOLOR, 0, 0L); + } + + COLORREF SetTextColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETTEXTCOLOR, 0, (LPARAM)clr); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + COLORREF GetLineColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETLINECOLOR, 0, 0L); + } + + COLORREF SetLineColor(COLORREF clrNew /*= CLR_DEFAULT*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETLINECOLOR, 0, (LPARAM)clrNew); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetItem(LPTVITEMEX pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(LPTVITEMEX pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + DWORD GetExtendedStyle() const + { +#ifndef TVM_GETEXTENDEDSTYLE + const UINT TVM_GETEXTENDEDSTYLE = (TV_FIRST + 45); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TVM_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask) + { +#ifndef TVM_SETEXTENDEDSTYLE + const UINT TVM_SETEXTENDEDSTYLE = (TV_FIRST + 44); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TVM_SETEXTENDEDSTYLE, dwMask, dwStyle); + } + +#if (_WIN32_WINNT >= 0x0600) + BOOL SetAutoScrollInfo(UINT uPixPerSec, UINT uUpdateTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETAUTOSCROLLINFO, (WPARAM)uPixPerSec, (LPARAM)uUpdateTime); + } + + DWORD GetSelectedCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TVM_GETSELECTEDCOUNT, 0, 0L); + } + + BOOL GetItemPartRect(HTREEITEM hItem, TVITEMPART partID, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVGETITEMPARTRECTINFO gipri = { hItem, lpRect, partID }; + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMPARTRECT, 0, (LPARAM)&gipri); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); + } + + HTREEITEM InsertItem(LPCTSTR lpszItem, int nImage, + int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter); + } + + HTREEITEM InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter); + } + + HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, + HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = hParent; + tvis.hInsertAfter = hInsertAfter; + tvis.item.mask = nMask; + tvis.item.pszText = (LPTSTR) lpszItem; + tvis.item.iImage = nImage; + tvis.item.iSelectedImage = nSelectedImage; + tvis.item.state = nState; + tvis.item.stateMask = nStateMask; + tvis.item.lParam = lParam; + return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis); + } + + BOOL DeleteItem(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)hItem); + } + + BOOL DeleteAllItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); + } + + BOOL Expand(HTREEITEM hItem, UINT nCode = TVE_EXPAND) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_EXPAND, nCode, (LPARAM)hItem); + } + + HTREEITEM GetNextItem(HTREEITEM hItem, UINT nCode) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem); + } + + HTREEITEM GetChildItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); + } + + HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); + } + + HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem); + } + + HTREEITEM GetParentItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); + } + + HTREEITEM GetFirstVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L); + } + + HTREEITEM GetNextVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem); + } + + HTREEITEM GetPrevVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem); + } + + HTREEITEM GetSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L); + } + + HTREEITEM GetDropHilightItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L); + } + + HTREEITEM GetRootItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L); + } + +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + HTREEITEM GetLastVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L); + } +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0600) + HTREEITEM GetNextSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L); + } +#endif // (_WIN32_IE >= 0x0600) + + BOOL Select(HTREEITEM hItem, UINT nCode) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, nCode, (LPARAM)hItem); + } + + BOOL SelectItem(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); + } + + BOOL SelectDropTarget(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItem); + } + + BOOL SelectSetFirstVisible(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, (LPARAM)hItem); + } + + CEdit EditLabel(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, TVM_EDITLABEL, 0, (LPARAM)hItem)); + } + + BOOL EndEditLabelNow(BOOL bCancel) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_ENDEDITLABELNOW, bCancel, 0L); + } + + HTREEITEM HitTest(TVHITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo); + } + + HTREEITEM HitTest(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVHITTESTINFO hti = { 0 }; + hti.pt = pt; + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return hTreeItem; + } + + BOOL SortChildren(HTREEITEM hItem, BOOL bRecurse = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDREN, (WPARAM)bRecurse, (LPARAM)hItem); + } + + BOOL EnsureVisible(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem); + } + + BOOL SortChildrenCB(LPTVSORTCB pSort, BOOL bRecurse = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDRENCB, (WPARAM)bRecurse, (LPARAM)pSort); + } + + CImageList RemoveImageList(int nImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageList, NULL)); + } + + CImageList CreateDragImage(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItem)); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL SetInsertMark(HTREEITEM hTreeItem, BOOL bAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, bAfter, (LPARAM)hTreeItem); + } + + BOOL RemoveInsertMark() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, 0, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + HTREEITEM MapAccIDToHTREEITEM(UINT uID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L); + } + + UINT MapHTREEITEMToAccID(HTREEITEM hTreeItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_MAPHTREEITEMTOACCID, (WPARAM)hTreeItem, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + void ShowInfoTip(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TVM_SHOWINFOTIP, 0, (LPARAM)hItem); + } +#endif // (_WIN32_WINNT >= 0x0600) +}; + +typedef CTreeViewCtrlT CTreeViewCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTreeViewCtrlEx + +// forward declaration +template class CTreeViewCtrlExT; + +// Note: TBase here is for CTreeViewCtrlExT, and not for CTreeItemT itself +template +class CTreeItemT +{ +public: + HTREEITEM m_hTreeItem; + CTreeViewCtrlExT* m_pTreeView; + +// Construction + CTreeItemT(HTREEITEM hTreeItem = NULL, CTreeViewCtrlExT* pTreeView = NULL) : m_hTreeItem(hTreeItem), m_pTreeView(pTreeView) + { } + + CTreeItemT(const CTreeItemT& posSrc) + { + *this = posSrc; + } + + operator HTREEITEM() { return m_hTreeItem; } + + CTreeItemT& operator =(const CTreeItemT& itemSrc) + { + m_hTreeItem = itemSrc.m_hTreeItem; + m_pTreeView = itemSrc.m_pTreeView; + return *this; + } + +// Attributes + CTreeViewCtrlExT* GetTreeView() const { return m_pTreeView; } + + BOOL operator !() const { return m_hTreeItem == NULL; } + + BOOL IsNull() const { return m_hTreeItem == NULL; } + + BOOL GetRect(LPRECT lpRect, BOOL bTextOnly) const; + BOOL GetText(LPTSTR lpstrText, int nLen) const; +#ifndef _ATL_NO_COM + BOOL GetText(BSTR& bstrText) const; +#endif // !_ATL_NO_COM +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetText(_CSTRING_NS::CString& strText) const; +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL SetText(LPCTSTR lpszItem); + BOOL GetImage(int& nImage, int& nSelectedImage) const; + BOOL SetImage(int nImage, int nSelectedImage); + UINT GetState(UINT nStateMask) const; + BOOL SetState(UINT nState, UINT nStateMask); + DWORD_PTR GetData() const; + BOOL SetData(DWORD_PTR dwData); + BOOL SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam); + +// Operations + CTreeItemT InsertAfter(LPCTSTR lpstrItem, HTREEITEM hItemAfter, int nImageIndex) + { + return _Insert(lpstrItem, nImageIndex, hItemAfter); + } + + CTreeItemT AddHead(LPCTSTR lpstrItem, int nImageIndex) + { + return _Insert(lpstrItem, nImageIndex, TVI_FIRST); + } + + CTreeItemT AddTail(LPCTSTR lpstrItem, int nImageIndex) + { + return _Insert(lpstrItem, nImageIndex, TVI_LAST); + } + + CTreeItemT GetChild() const; + CTreeItemT GetNext(UINT nCode) const; + CTreeItemT GetNextSibling() const; + CTreeItemT GetPrevSibling() const; + CTreeItemT GetParent() const; + CTreeItemT GetFirstVisible() const; + CTreeItemT GetNextVisible() const; + CTreeItemT GetPrevVisible() const; + CTreeItemT GetSelected() const; + CTreeItemT GetDropHilight() const; + CTreeItemT GetRoot() const; +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + CTreeItemT GetLastVisible() const; +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0600) + CTreeItemT GetNextSelected() const; +#endif // (_WIN32_IE >= 0x0600) + BOOL HasChildren() const; + BOOL Delete(); + BOOL Expand(UINT nCode = TVE_EXPAND); + BOOL Select(UINT nCode); + BOOL Select(); + BOOL SelectDropTarget(); + BOOL SelectSetFirstVisible(); + HWND EditLabel(); + HIMAGELIST CreateDragImage(); + BOOL SortChildren(BOOL bRecurse = FALSE); + BOOL EnsureVisible(); + CTreeItemT _Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter); + int GetImageIndex() const; +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL SetInsertMark(BOOL bAfter); +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) +#if (_WIN32_WINNT >= 0x0501) + UINT MapHTREEITEMToAccID() const; +#endif // (_WIN32_WINNT >= 0x0501) +#if (_WIN32_WINNT >= 0x0600) + void ShowInfoTip(); + BOOL GetPartRect(TVITEMPART partID, LPRECT lpRect) const; +#endif // (_WIN32_WINNT >= 0x0600) +}; + +typedef CTreeItemT CTreeItem; + + +template +class CTreeViewCtrlExT : public CTreeViewCtrlT< TBase > +{ +public: +// Constructors + CTreeViewCtrlExT(HWND hWnd = NULL) : CTreeViewCtrlT< TBase >(hWnd) + { } + + CTreeViewCtrlExT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Operations (overides that return CTreeItem) + CTreeItemT InsertItem(LPTVINSERTSTRUCT lpInsertStruct) + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); + return CTreeItemT(hTreeItem, this); + } + + CTreeItemT InsertItem(LPCTSTR lpszItem, int nImage, + int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter); + } + + CTreeItemT InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter); + } + + CTreeItemT GetNextItem(HTREEITEM hItem, UINT nCode) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetChildItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetNextSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetPrevSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetParentItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetFirstVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetNextVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetPrevVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetDropHilightItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetRootItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + CTreeItemT GetLastVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0600) + CTreeItemT GetNextSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } +#endif // (_WIN32_IE >= 0x0600) + + CTreeItemT HitTest(TVHITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, + HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = hParent; + tvis.hInsertAfter = hInsertAfter; + tvis.item.mask = nMask; + tvis.item.pszText = (LPTSTR) lpszItem; + tvis.item.iImage = nImage; + tvis.item.iSelectedImage = nSelectedImage; + tvis.item.state = nState; + tvis.item.stateMask = nStateMask; + tvis.item.lParam = lParam; + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis); + return CTreeItemT(hTreeItem, this); + } + + CTreeItemT HitTest(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVHITTESTINFO hti = { 0 }; + hti.pt = pt; + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + +#if (_WIN32_WINNT >= 0x0501) + CTreeItemT MapAccIDToHTREEITEM(UINT uID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } +#endif // (_WIN32_WINNT >= 0x0501) +}; + +typedef CTreeViewCtrlExT CTreeViewCtrlEx; + + +// CTreeItem inline methods +template +inline BOOL CTreeItemT::GetRect(LPRECT lpRect, BOOL bTextOnly) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemRect(m_hTreeItem,lpRect,bTextOnly); +} + +template +inline CTreeItemT CTreeItemT::GetNext(UINT nCode) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextItem(m_hTreeItem,nCode); +} + +template +inline CTreeItemT CTreeItemT::GetChild() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetChildItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetNextSibling() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextSiblingItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetPrevSibling() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetPrevSiblingItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetParent() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetParentItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetFirstVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetFirstVisibleItem(); +} + +template +inline CTreeItemT CTreeItemT::GetNextVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextVisibleItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetPrevVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetPrevVisibleItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetSelected() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetSelectedItem(); +} + +template +inline CTreeItemT CTreeItemT::GetDropHilight() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetDropHilightItem(); +} + +template +inline CTreeItemT CTreeItemT::GetRoot() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetRootItem(); +} + +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) +template +inline CTreeItemT CTreeItemT::GetLastVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetLastVisibleItem(); +} +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0600) +template +inline CTreeItemT CTreeItemT::GetNextSelected() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextSelectedItem(); +} +#endif // (_WIN32_IE >= 0x0600) + +template +inline BOOL CTreeItemT::GetText(LPTSTR lpstrText, int nLen) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemText(m_hTreeItem, lpstrText, nLen); +} + +#ifndef _ATL_NO_COM +#ifdef _OLEAUTO_H_ +template +inline BOOL CTreeItemT::GetText(BSTR& bstrText) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemText(m_hTreeItem, bstrText); +} +#endif // _OLEAUTO_H_ +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) +template +inline BOOL CTreeItemT::GetText(_CSTRING_NS::CString& strText) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemText(m_hTreeItem, strText); +} +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + +template +inline BOOL CTreeItemT::GetImage(int& nImage, int& nSelectedImage) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemImage(m_hTreeItem,nImage,nSelectedImage); +} + +template +inline UINT CTreeItemT::GetState(UINT nStateMask) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemState(m_hTreeItem,nStateMask); +} + +template +inline DWORD_PTR CTreeItemT::GetData() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemData(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItem(m_hTreeItem, nMask, lpszItem, nImage, nSelectedImage, nState, nStateMask, lParam); +} + +template +inline BOOL CTreeItemT::SetText(LPCTSTR lpszItem) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemText(m_hTreeItem,lpszItem); +} + +template +inline BOOL CTreeItemT::SetImage(int nImage, int nSelectedImage) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemImage(m_hTreeItem,nImage,nSelectedImage); +} + +template +inline BOOL CTreeItemT::SetState(UINT nState, UINT nStateMask) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemState(m_hTreeItem,nState,nStateMask); +} + +template +inline BOOL CTreeItemT::SetData(DWORD_PTR dwData) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemData(m_hTreeItem,dwData); +} + +template +inline BOOL CTreeItemT::HasChildren() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->ItemHasChildren(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::Delete() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->DeleteItem(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::Expand(UINT nCode /*= TVE_EXPAND*/) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->Expand(m_hTreeItem,nCode); +} + +template +inline BOOL CTreeItemT::Select(UINT nCode) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->Select(m_hTreeItem,nCode); +} + +template +inline BOOL CTreeItemT::Select() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SelectItem(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SelectDropTarget() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SelectDropTarget(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SelectSetFirstVisible() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SelectSetFirstVisible(m_hTreeItem); +} + +template +inline HWND CTreeItemT::EditLabel() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->EditLabel(m_hTreeItem); +} + +template +inline HIMAGELIST CTreeItemT::CreateDragImage() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->CreateDragImage(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SortChildren(BOOL bRecurse /*= FALSE*/) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SortChildren(m_hTreeItem, bRecurse); +} + +template +inline BOOL CTreeItemT::EnsureVisible() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->EnsureVisible(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::_Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter) +{ + ATLASSERT(m_pTreeView != NULL); + TVINSERTSTRUCT ins = { 0 }; + ins.hParent = m_hTreeItem; + ins.hInsertAfter = hItemAfter; + ins.item.mask = TVIF_TEXT; + ins.item.pszText = (LPTSTR)lpstrItem; + if(nImageIndex != -1) + { + ins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE; + ins.item.iImage = nImageIndex; + ins.item.iSelectedImage = nImageIndex; + } + return CTreeItemT(m_pTreeView->InsertItem(&ins), m_pTreeView); +} + +template +inline int CTreeItemT::GetImageIndex() const +{ + ATLASSERT(m_pTreeView != NULL); + TVITEM item = { 0 }; + item.mask = TVIF_HANDLE | TVIF_IMAGE; + item.hItem = m_hTreeItem; + m_pTreeView->GetItem(&item); + return item.iImage; +} + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) +template +inline BOOL CTreeItemT::SetInsertMark(BOOL bAfter) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetInsertMark(m_hTreeItem, bAfter); +} +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) +template +inline UINT CTreeItemT::MapHTREEITEMToAccID() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->MapHTREEITEMToAccID(m_hTreeItem); +} +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) +template +inline void CTreeItemT::ShowInfoTip() +{ + ATLASSERT(m_pTreeView != NULL); + m_pTreeView->ShowInfoTip(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::GetPartRect(TVITEMPART partID, LPRECT lpRect) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemPartRect(m_hTreeItem, partID, lpRect); +} +#endif // (_WIN32_WINNT >= 0x0600) + + +/////////////////////////////////////////////////////////////////////////////// +// CToolBarCtrl + +template +class CToolBarCtrlT : public TBase +{ +public: +// Construction + CToolBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CToolBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return TOOLBARCLASSNAME; + } + + BOOL IsButtonEnabled(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONENABLED, nID, 0L); + } + + BOOL IsButtonChecked(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONCHECKED, nID, 0L); + } + + BOOL IsButtonPressed(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONPRESSED, nID, 0L); + } + + BOOL IsButtonHidden(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return(BOOL) ::SendMessage(m_hWnd, TB_ISBUTTONHIDDEN, nID, 0L); + } + + BOOL IsButtonIndeterminate(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONINDETERMINATE, nID, 0L); + } + + int GetState(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETSTATE, nID, 0L); + } + + BOOL SetState(int nID, UINT nState) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETSTATE, nID, MAKELPARAM(nState, 0)); + } + + BOOL GetButton(int nIndex, LPTBBUTTON lpButton) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETBUTTON, nIndex, (LPARAM)lpButton); + } + + int GetButtonCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_BUTTONCOUNT, 0, 0L); + } + + BOOL GetItemRect(int nIndex, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETITEMRECT, nIndex, (LPARAM)lpRect); + } + + void SetButtonStructSize(int nSize = sizeof(TBBUTTON)) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, nSize, 0L); + } + + BOOL SetButtonSize(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(size.cx, size.cy)); + } + + BOOL SetButtonSize(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cy)); + } + + BOOL SetBitmapSize(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(size.cx, size.cy)); + } + + BOOL SetBitmapSize(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(cx, cy)); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TB_GETTOOLTIPS, 0, 0L)); + } + + void SetToolTips(HWND hWndToolTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L); + } +#endif // !_WIN32_WCE + + void SetNotifyWnd(HWND hWnd) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETPARENT, (WPARAM)hWnd, 0L); + } + + int GetRows() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETROWS, 0, 0L); + } + + void SetRows(int nRows, BOOL bLarger, LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETROWS, MAKELPARAM(nRows, bLarger), (LPARAM)lpRect); + } + + BOOL SetCmdID(int nIndex, UINT nID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETCMDID, nIndex, nID); + } + + DWORD GetBitmapFlags() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETBITMAPFLAGS, 0, 0L); + } + + int GetBitmap(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETBITMAP, nID, 0L); + } + + int GetButtonText(int nID, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETBUTTONTEXT, nID, (LPARAM)lpstrText); + } + + // nIndex - IE5 or higher only + CImageList GetImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETIMAGELIST, nIndex, 0L)); + } + + // nIndex - IE5 or higher only + CImageList SetImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETIMAGELIST, nIndex, (LPARAM)hImageList)); + } + + // nIndex - IE5 or higher only + CImageList GetDisabledImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETDISABLEDIMAGELIST, nIndex, 0L)); + } + + // nIndex - IE5 or higher only + CImageList SetDisabledImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETDISABLEDIMAGELIST, nIndex, (LPARAM)hImageList)); + } + +#ifndef _WIN32_WCE + // nIndex - IE5 or higher only + CImageList GetHotImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETHOTIMAGELIST, nIndex, 0L)); + } + + // nIndex - IE5 or higher only + CImageList SetHotImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETHOTIMAGELIST, nIndex, (LPARAM)hImageList)); + } +#endif // !_WIN32_WCE + + DWORD GetStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETSTYLE, 0, 0L); + } + + void SetStyle(DWORD dwStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETSTYLE, 0, dwStyle); + } + + DWORD GetButtonSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L); + } + + void GetButtonSize(SIZE& size) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L); + size.cx = LOWORD(dwRet); + size.cy = HIWORD(dwRet); + } + + BOOL GetRect(int nID, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETRECT, nID, (LPARAM)lpRect); + } + + int GetTextRows() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETTEXTROWS, 0, 0L); + } + + BOOL SetButtonWidth(int cxMin, int cxMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cxMin, cxMax)); + } + + BOOL SetIndent(int nIndent) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETINDENT, nIndent, 0L); + } + + BOOL SetMaxTextRows(int nMaxTextRows) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, nMaxTextRows, 0L); + } + +#if (_WIN32_IE >= 0x0400) +#ifndef _WIN32_WCE + BOOL GetAnchorHighlight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETANCHORHIGHLIGHT, 0, 0L); + } + + BOOL SetAnchorHighlight(BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETANCHORHIGHLIGHT, bEnable, 0L); + } +#endif // !_WIN32_WCE + + int GetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETBUTTONINFO, nID, (LPARAM)lptbbi); + } + + BOOL SetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)lptbbi); + } + + BOOL SetButtonInfo(int nID, DWORD dwMask, BYTE Style, BYTE State, LPCTSTR lpszItem, + int iImage, WORD cx, int iCommand, DWORD_PTR lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBBUTTONINFO tbbi = { 0 }; + tbbi.cbSize = sizeof(TBBUTTONINFO); + tbbi.dwMask = dwMask; + tbbi.idCommand = iCommand; + tbbi.iImage = iImage; + tbbi.fsState = State; + tbbi.fsStyle = Style; + tbbi.cx = cx; + tbbi.pszText = (LPTSTR) lpszItem; + tbbi.lParam = lParam; + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)&tbbi); + } + +#ifndef _WIN32_WCE + int GetHotItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETHOTITEM, 0, 0L); + } + + int SetHotItem(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_SETHOTITEM, nItem, 0L); + } +#endif // !_WIN32_WCE + + BOOL IsButtonHighlighted(int nButtonID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONHIGHLIGHTED, nButtonID, 0L); + } + + DWORD SetDrawTextFlags(DWORD dwMask, DWORD dwFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_SETDRAWTEXTFLAGS, dwMask, dwFlags); + } + +#ifndef _WIN32_WCE + BOOL GetColorScheme(LPCOLORSCHEME lpcs) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETCOLORSCHEME, 0, (LPARAM)lpcs); + } + + void SetColorScheme(LPCOLORSCHEME lpcs) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETCOLORSCHEME, 0, (LPARAM)lpcs); + } + + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, dwStyle); + } + + void GetInsertMark(LPTBINSERTMARK lptbim) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_GETINSERTMARK, 0, (LPARAM)lptbim); + } + + void SetInsertMark(LPTBINSERTMARK lptbim) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETINSERTMARK, 0, (LPARAM)lptbim); + } + + COLORREF GetInsertMarkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TB_GETINSERTMARKCOLOR, 0, 0L); + } + + COLORREF SetInsertMarkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TB_SETINSERTMARKCOLOR, 0, (LPARAM)clr); + } + + BOOL GetMaxSize(LPSIZE lpSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETMAXSIZE, 0, (LPARAM)lpSize); + } + + void GetPadding(LPSIZE lpSizePadding) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpSizePadding != NULL); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETPADDING, 0, 0L); + lpSizePadding->cx = GET_X_LPARAM(dwRet); + lpSizePadding->cy = GET_Y_LPARAM(dwRet); + } + + void SetPadding(int cx, int cy, LPSIZE lpSizePadding = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_SETPADDING, 0, MAKELPARAM(cx, cy)); + if(lpSizePadding != NULL) + { + lpSizePadding->cx = GET_X_LPARAM(dwRet); + lpSizePadding->cy = GET_Y_LPARAM(dwRet); + } + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int GetString(int nString, LPTSTR lpstrString, int cchMaxLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(cchMaxLen, nString), (LPARAM)lpstrString); + } + + int GetStringBSTR(int nString, BSTR& bstrString) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrString == NULL); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL)); + if(nLength != -1) + { + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLength + 1); + if(lpstrText != NULL) + { + nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstrText); + if(nLength != -1) + bstrString = ::SysAllocString(T2OLE(lpstrText)); + } + else + { + nLength = -1; + } + } + + return nLength; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetString(int nString, _CSTRING_NS::CString& str) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL)); + if(nLength != -1) + { + LPTSTR lpstr = str.GetBufferSetLength(nLength + 1); + if(lpstr != NULL) + nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstr); + else + nLength = -1; + str.ReleaseBuffer(); + } + return nLength; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + void GetMetrics(LPTBMETRICS lptbm) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_GETMETRICS, 0, (LPARAM)lptbm); + } + + void SetMetrics(LPTBMETRICS lptbm) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETMETRICS, 0, (LPARAM)lptbm); + } + + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + CImageList GetPressedImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETPRESSEDIMAGELIST, nIndex, 0L)); + } + + CImageList SetPressedImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETPRESSEDIMAGELIST, nIndex, (LPARAM)hImageList)); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + BOOL EnableButton(int nID, BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ENABLEBUTTON, nID, MAKELPARAM(bEnable, 0)); + } + + BOOL CheckButton(int nID, BOOL bCheck = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_CHECKBUTTON, nID, MAKELPARAM(bCheck, 0)); + } + + BOOL PressButton(int nID, BOOL bPress = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_PRESSBUTTON, nID, MAKELPARAM(bPress, 0)); + } + + BOOL HideButton(int nID, BOOL bHide = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_HIDEBUTTON, nID, MAKELPARAM(bHide, 0)); + } + + BOOL Indeterminate(int nID, BOOL bIndeterminate = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_INDETERMINATE, nID, MAKELPARAM(bIndeterminate, 0)); + } + + int AddBitmap(int nNumButtons, UINT nBitmapID) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBADDBITMAP tbab = { 0 }; + tbab.hInst = ModuleHelper::GetResourceInstance(); + ATLASSERT(tbab.hInst != NULL); + tbab.nID = nBitmapID; + return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab); + } + + int AddBitmap(int nNumButtons, HBITMAP hBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBADDBITMAP tbab = { 0 }; + tbab.hInst = NULL; + tbab.nID = (UINT_PTR)hBitmap; + return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab); + } + + BOOL AddButtons(int nNumButtons, LPTBBUTTON lpButtons) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ADDBUTTONS, nNumButtons, (LPARAM)lpButtons); + } + + BOOL InsertButton(int nIndex, LPTBBUTTON lpButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)lpButton); + } + + BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap, + INT_PTR iString, DWORD_PTR lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBBUTTON tbb = { 0 }; + tbb.fsStyle = Style; + tbb.fsState = State; + tbb.idCommand = iCommand; + tbb.iBitmap = iBitmap; + tbb.iString = iString; + tbb.dwData = lParam; + return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)&tbb); + } + + BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap, + LPCTSTR lpszItem, DWORD_PTR lParam) + { + return InsertButton(nIndex, iCommand, Style, State, iBitmap, (INT_PTR)lpszItem, lParam); + } + + BOOL AddButton(LPTBBUTTON lpButton) + { + return InsertButton(-1, lpButton); + } + + BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, INT_PTR iString, DWORD_PTR lParam) + { + return InsertButton(-1, iCommand, Style, State, iBitmap, iString, lParam); + } + + BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, LPCTSTR lpszItem, DWORD_PTR lParam) + { + return InsertButton(-1, iCommand, Style, State, iBitmap, lpszItem, lParam); + } + + BOOL DeleteButton(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_DELETEBUTTON, nIndex, 0L); + } + + UINT CommandToIndex(UINT nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TB_COMMANDTOINDEX, nID, 0L); + } + +#ifndef _WIN32_WCE + void SaveState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBSAVEPARAMS tbs = { 0 }; + tbs.hkr = hKeyRoot; + tbs.pszSubKey = lpszSubKey; + tbs.pszValueName = lpszValueName; + ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)TRUE, (LPARAM)&tbs); + } + + void RestoreState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBSAVEPARAMS tbs = { 0 }; + tbs.hkr = hKeyRoot; + tbs.pszSubKey = lpszSubKey; + tbs.pszValueName = lpszValueName; + ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)FALSE, (LPARAM)&tbs); + } + + void Customize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_CUSTOMIZE, 0, 0L); + } +#endif // !_WIN32_WCE + + int AddString(UINT nStringID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)ModuleHelper::GetResourceInstance(), (LPARAM)nStringID); + } + + int AddStrings(LPCTSTR lpszStrings) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_ADDSTRING, 0, (LPARAM)lpszStrings); + } + + void AutoSize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0L); + } + + BOOL ChangeBitmap(int nID, int nBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_CHANGEBITMAP, nID, MAKELPARAM(nBitmap, 0)); + } + + int LoadImages(int nBitmapID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)ModuleHelper::GetResourceInstance()); + } + + int LoadStdImages(int nBitmapID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)HINST_COMMCTRL); + } + + BOOL ReplaceBitmap(LPTBREPLACEBITMAP ptbrb) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_REPLACEBITMAP, 0, (LPARAM)ptbrb); + } + +#if (_WIN32_IE >= 0x0400) + int HitTest(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_HITTEST, 0, (LPARAM)lpPoint); + } + +#ifndef _WIN32_WCE + BOOL InsertMarkHitTest(LPPOINT lpPoint, LPTBINSERTMARK lptbim) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)lptbim); + } + + BOOL InsertMarkHitTest(int x, int y, LPTBINSERTMARK lptbim) const + { + ATLASSERT(::IsWindow(m_hWnd)); + POINT pt = { x, y }; + return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)&pt, (LPARAM)lptbim); + } + + BOOL MapAccelerator(TCHAR chAccel, int& nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_MAPACCELERATOR, (WPARAM)chAccel, (LPARAM)&nID); + } + + BOOL MarkButton(int nID, BOOL bHighlight = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_MARKBUTTON, nID, MAKELPARAM(bHighlight, 0)); + } + + BOOL MoveButton(int nOldPos, int nNewPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_MOVEBUTTON, nOldPos, nNewPos); + } + + HRESULT GetObject(REFIID iid, LPVOID* ppvObject) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HRESULT)::SendMessage(m_hWnd, TB_GETOBJECT, (WPARAM)&iid, (LPARAM)ppvObject); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) +}; + +typedef CToolBarCtrlT CToolBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CStatusBarCtrl + +template +class CStatusBarCtrlT : public TBase +{ +public: +// Constructors + CStatusBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CStatusBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Methods + static LPCTSTR GetWndClassName() + { + return STATUSCLASSNAME; + } + + int GetParts(int nParts, int* pParts) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, SB_GETPARTS, nParts, (LPARAM)pParts); + } + + BOOL SetParts(int nParts, int* pWidths) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_SETPARTS, nParts, (LPARAM)pWidths); + } + + int GetTextLength(int nPane, int* pType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L); + if (pType != NULL) + *pType = (int)(short)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + int GetText(int nPane, LPTSTR lpszText, int* pType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane, (LPARAM)lpszText); + if(pType != NULL) + *pType = (int)(short)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + +#ifndef _ATL_NO_COM + BOOL GetTextBSTR(int nPane, BSTR& bstrText, int* pType = NULL) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + ATLASSERT(bstrText == NULL); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L)); + if(nLength == 0) + return FALSE; + + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLength + 1); + if(lpstrText == NULL) + return FALSE; + + if(!GetText(nPane, lpstrText, pType)) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpstrText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetText(int nPane, _CSTRING_NS::CString& strText, int* pType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L)); + if(nLength == 0) + return 0; + + LPTSTR lpstr = strText.GetBufferSetLength(nLength); + if(lpstr == NULL) + return 0; + return GetText(nPane, lpstr, pType); + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL SetText(int nPane, LPCTSTR lpszText, int nType = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (BOOL)::SendMessage(m_hWnd, SB_SETTEXT, (nPane | nType), (LPARAM)lpszText); + } + + BOOL GetRect(int nPane, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (BOOL)::SendMessage(m_hWnd, SB_GETRECT, nPane, (LPARAM)lpRect); + } + + BOOL GetBorders(int* pBorders) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)pBorders); + } + + BOOL GetBorders(int& nHorz, int& nVert, int& nSpacing) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int borders[3] = { 0, 0, 0 }; + BOOL bResult = (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)&borders); + if(bResult) + { + nHorz = borders[0]; + nVert = borders[1]; + nSpacing = borders[2]; + } + return bResult; + } + + void SetMinHeight(int nMin) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, SB_SETMINHEIGHT, nMin, 0L); + } + + BOOL SetSimple(BOOL bSimple = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_SIMPLE, bSimple, 0L); + } + + BOOL IsSimple() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_ISSIMPLE, 0, 0L); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_SETUNICODEFORMAT, bUnicode, 0L); + } + + void GetTipText(int nPane, LPTSTR lpstrText, int nSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + ::SendMessage(m_hWnd, SB_GETTIPTEXT, MAKEWPARAM(nPane, nSize), (LPARAM)lpstrText); + } + + void SetTipText(int nPane, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + ::SendMessage(m_hWnd, SB_SETTIPTEXT, nPane, (LPARAM)lpstrText); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) + COLORREF SetBkColor(COLORREF clrBk) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, SB_SETBKCOLOR, 0, (LPARAM)clrBk); + } + + HICON GetIcon(int nPane) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (HICON)::SendMessage(m_hWnd, SB_GETICON, nPane, 0L); + } + + BOOL SetIcon(int nPane, HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (BOOL)::SendMessage(m_hWnd, SB_SETICON, nPane, (LPARAM)hIcon); + } +#endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) +}; + +typedef CStatusBarCtrlT CStatusBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTabCtrl + +template +class CTabCtrlT : public TBase +{ +public: +// Constructors + CTabCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTabCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_TABCONTROL; + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_GETIMAGELIST, 0, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_SETIMAGELIST, 0, (LPARAM)hImageList)); + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETITEMCOUNT, 0, 0L); + } + + BOOL GetItem(int nItem, LPTCITEM pTabCtrlItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_GETITEM, nItem, (LPARAM)pTabCtrlItem); + } + + BOOL SetItem(int nItem, LPTCITEM pTabCtrlItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)pTabCtrlItem); + } + + int SetItem(int nItem, UINT mask, LPCTSTR lpszItem, DWORD dwState, DWORD dwStateMask, int iImage, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TCITEM tci = { 0 }; + tci.mask = mask; + tci.pszText = (LPTSTR) lpszItem; + tci.dwState = dwState; + tci.dwStateMask = dwStateMask; + tci.iImage = iImage; + tci.lParam = lParam; + return (int)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)&tci); + } + + BOOL GetItemRect(int nItem, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_GETITEMRECT, nItem, (LPARAM)lpRect); + } + + int GetCurSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETCURSEL, 0, 0L); + } + + int SetCurSel(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_SETCURSEL, nItem, 0L); + } + + SIZE SetItemSize(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwSize = (DWORD)::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(size.cx, size.cy)); + SIZE sizeRet = { GET_X_LPARAM(dwSize), GET_Y_LPARAM(dwSize) }; + return sizeRet; + } + + void SetItemSize(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(cx, cy)); + } + + void SetPadding(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETPADDING, 0, MAKELPARAM(size.cx, size.cy)); + } + + int GetRowCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETROWCOUNT, 0, 0L); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetTooltips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TCM_GETTOOLTIPS, 0, 0L)); + } + + void SetTooltips(HWND hWndToolTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L); + } +#endif // !_WIN32_WCE + + int GetCurFocus() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETCURFOCUS, 0, 0L); + } + + void SetCurFocus(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETCURFOCUS, nItem, 0L); + } + + BOOL SetItemExtra(int cbExtra) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetItemCount() == 0); // must be empty + return (BOOL)::SendMessage(m_hWnd, TCM_SETITEMEXTRA, cbExtra, 0L); + } + + int SetMinTabWidth(int nWidth = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_SETMINTABWIDTH, 0, nWidth); + } + +#if (_WIN32_IE >= 0x0400) + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TCM_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TCM_SETEXTENDEDSTYLE, dwExMask, dwExStyle); + } + +#ifndef _WIN32_WCE + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +// Operations + int InsertItem(int nItem, LPTCITEM pTabCtrlItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)pTabCtrlItem); + } + + int InsertItem(int nItem, UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TCITEM tci = { 0 }; + tci.mask = mask; + tci.pszText = (LPTSTR) lpszItem; + tci.iImage = iImage; + tci.lParam = lParam; + return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci); + } + + int InsertItem(int nItem, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + TCITEM tci = { 0 }; + tci.mask = TCIF_TEXT; + tci.pszText = (LPTSTR) lpszItem; + return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci); + } + + int AddItem(LPTCITEM pTabCtrlItem) + { + return InsertItem(GetItemCount(), pTabCtrlItem); + } + + int AddItem(UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam) + { + return InsertItem(GetItemCount(), mask, lpszItem, iImage, lParam); + } + + int AddItem(LPCTSTR lpszItem) + { + return InsertItem(GetItemCount(), lpszItem); + } + + BOOL DeleteItem(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_DELETEITEM, nItem, 0L); + } + + BOOL DeleteAllItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_DELETEALLITEMS, 0, 0L); + } + + void AdjustRect(BOOL bLarger, LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_ADJUSTRECT, bLarger, (LPARAM)lpRect); + } + + void RemoveImage(int nImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_REMOVEIMAGE, nImage, 0L); + } + + int HitTest(TC_HITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)pHitTestInfo); + } + + void DeselectAll(BOOL bExcludeFocus = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_DESELECTALL, bExcludeFocus, 0L); + } + +#if (_WIN32_IE >= 0x0400) + BOOL HighlightItem(int nIndex, BOOL bHighlight = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_HIGHLIGHTITEM, nIndex, MAKELPARAM(bHighlight, 0)); + } +#endif // (_WIN32_IE >= 0x0400) +}; + +typedef CTabCtrlT CTabCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTrackBarCtrl + +template +class CTrackBarCtrlT : public TBase +{ +public: +// Constructors + CTrackBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTrackBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return TRACKBAR_CLASS; + } + + int GetLineSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETLINESIZE, 0, 0L); + } + + int SetLineSize(int nSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_SETLINESIZE, 0, nSize); + } + + int GetPageSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETPAGESIZE, 0, 0L); + } + + int SetPageSize(int nSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_SETPAGESIZE, 0, nSize); + } + + int GetRangeMin() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETRANGEMIN, 0, 0L); + } + + void SetRangeMin(int nMin, BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETRANGEMIN, bRedraw, nMin); + } + + int GetRangeMax() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETRANGEMAX, 0, 0L); + } + + void SetRangeMax(int nMax, BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETRANGEMAX, bRedraw, nMax); + } + + void GetRange(int& nMin, int& nMax) const + { + nMin = GetRangeMin(); + nMax = GetRangeMax(); + } + + void SetRange(int nMin, int nMax, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETRANGE, bRedraw, MAKELPARAM(nMin, nMax)); + } + + int GetSelStart() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETSELSTART, 0, 0L); + } + + void SetSelStart(int nMin) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETSELSTART, 0, (LPARAM)nMin); + } + + int GetSelEnd() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETSELEND, 0, 0L); + } + + void SetSelEnd(int nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETSELEND, 0, (LPARAM)nMax); + } + + void GetSelection(int& nMin, int& nMax) const + { + nMin = GetSelStart(); + nMax = GetSelEnd(); + } + + void SetSelection(int nMin, int nMax) + { + SetSelStart(nMin); + SetSelEnd(nMax); + } + + void GetChannelRect(LPRECT lprc) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_GETCHANNELRECT, 0, (LPARAM)lprc); + } + + void GetThumbRect(LPRECT lprc) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_GETTHUMBRECT, 0, (LPARAM)lprc); + } + + int GetPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETPOS, 0, 0L); + } + + void SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETPOS, TRUE, nPos); + } + + UINT GetNumTics() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TBM_GETNUMTICS, 0, 0L); + } + + DWORD* GetTicArray() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD*)::SendMessage(m_hWnd, TBM_GETPTICS, 0, 0L); + } + + int GetTic(int nTic) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETTIC, nTic, 0L); + } + + BOOL SetTic(int nTic) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TBM_SETTIC, 0, nTic); + } + + int GetTicPos(int nTic) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETTICPOS, nTic, 0L); + } + + void SetTicFreq(int nFreq) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETTICFREQ, nFreq, 0L); + } + + int GetThumbLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETTHUMBLENGTH, 0, 0L); + } + + void SetThumbLength(int nLength) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETTHUMBLENGTH, nLength, 0L); + } + + void SetSel(int nStart, int nEnd, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & TBS_ENABLESELRANGE) != 0); + ::SendMessage(m_hWnd, TBM_SETSEL, bRedraw, MAKELPARAM(nStart, nEnd)); + } + + ATL::CWindow GetBuddy(BOOL bLeft = TRUE) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_GETBUDDY, bLeft, 0L)); + } + + ATL::CWindow SetBuddy(HWND hWndBuddy, BOOL bLeft = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_SETBUDDY, bLeft, (LPARAM)hWndBuddy)); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TBM_GETTOOLTIPS, 0, 0L)); + } + + void SetToolTips(HWND hWndTT) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETTOOLTIPS, (WPARAM)hWndTT, 0L); + } + + int SetTipSide(int nSide) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_SETTIPSIDE, nSide, 0L); + } +#endif // !_WIN32_WCE + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TBM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TBM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +// Operations + void ClearSel(BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_CLEARSEL, bRedraw, 0L); + } + + void VerifyPos() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETPOS, FALSE, 0L); + } + + void ClearTics(BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_CLEARTICS, bRedraw, 0L); + } +}; + +typedef CTrackBarCtrlT CTrackBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CUpDownCtrl + +template +class CUpDownCtrlT : public TBase +{ +public: +// Constructors + CUpDownCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CUpDownCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return UPDOWN_CLASS; + } + + UINT GetAccel(int nAccel, UDACCEL* pAccel) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETACCEL, nAccel, (LPARAM)pAccel)); + } + + BOOL SetAccel(int nAccel, UDACCEL* pAccel) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)LOWORD(::SendMessage(m_hWnd, UDM_SETACCEL, nAccel, (LPARAM)pAccel)); + } + + UINT GetBase() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETBASE, 0, 0L)); + } + + int SetBase(int nBase) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, UDM_SETBASE, nBase, 0L); + } + + ATL::CWindow GetBuddy() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_GETBUDDY, 0, 0L)); + } + + ATL::CWindow SetBuddy(HWND hWndBuddy) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_SETBUDDY, (WPARAM)hWndBuddy, 0L)); + } + + int GetPos(LPBOOL lpbError = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETPOS, 0, 0L); + // Note: Seems that Windows always sets error to TRUE if + // UDS_SETBUDDYINT style is not used + if(lpbError != NULL) + *lpbError = (HIWORD(dwRet) != 0) ? TRUE : FALSE; + return (int)(short)LOWORD(dwRet); + } + + int SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, UDM_SETPOS, 0, MAKELPARAM(nPos, 0))); + } + + DWORD GetRange() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L); + } + + void GetRange(int& nLower, int& nUpper) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L); + nLower = (int)(short)HIWORD(dwRet); + nUpper = (int)(short)LOWORD(dwRet); + } + + void SetRange(int nLower, int nUpper) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, UDM_SETRANGE, 0, MAKELPARAM(nUpper, nLower)); + } + +#if (_WIN32_IE >= 0x0400) + void SetRange32(int nLower, int nUpper) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, UDM_SETRANGE32, nLower, nUpper); + } + + void GetRange32(int& nLower, int& nUpper) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, UDM_GETRANGE32, (WPARAM)&nLower, (LPARAM)&nUpper); + } + +#ifndef _WIN32_WCE + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, UDM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, UDM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int GetPos32(LPBOOL lpbError = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + // Note: Seems that Windows always sets error to TRUE if + // UDS_SETBUDDYINT style is not used + return (int)::SendMessage(m_hWnd, UDM_GETPOS32, 0, (LPARAM)lpbError); + } + + int SetPos32(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, UDM_SETPOS32, 0, (LPARAM)nPos); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CUpDownCtrlT CUpDownCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CProgressBarCtrl + +template +class CProgressBarCtrlT : public TBase +{ +public: +// Constructors + CProgressBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CProgressBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return PROGRESS_CLASS; + } + + DWORD SetRange(int nLower, int nUpper) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE, 0, MAKELPARAM(nLower, nUpper)); + } + + int SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETPOS, nPos, 0L)); + } + + int OffsetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_DELTAPOS, nPos, 0L)); + } + + int SetStep(int nStep) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETSTEP, nStep, 0L)); + } + + UINT GetPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, PBM_GETPOS, 0, 0L); + } + + void GetRange(PPBRANGE pPBRange) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pPBRange != NULL); + ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)pPBRange); + } + + void GetRange(int& nLower, int& nUpper) const + { + ATLASSERT(::IsWindow(m_hWnd)); + PBRANGE range = { 0 }; + ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)&range); + nLower = range.iLow; + nUpper = range.iHigh; + } + + int GetRangeLimit(BOOL bLowLimit) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_GETRANGE, bLowLimit, (LPARAM)NULL); + } + + DWORD SetRange32(int nMin, int nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE32, nMin, nMax); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + COLORREF SetBarColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_SETBARCOLOR, 0, (LPARAM)clr); + } + + COLORREF SetBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_SETBKCOLOR, 0, (LPARAM)clr); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE) + BOOL SetMarquee(BOOL bMarquee, UINT uUpdateTime = 0U) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PBM_SETMARQUEE, (WPARAM)bMarquee, (LPARAM)uUpdateTime); + } +#endif // (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE) + +#if (_WIN32_WINNT >= 0x0600) + int GetStep() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_GETSTEP, 0, 0L); + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_GETBKCOLOR, 0, 0L); + } + + COLORREF GetBarColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_GETBARCOLOR, 0, 0L); + } + + int GetState() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_GETSTATE, 0, 0L); + } + + int SetState(int nState) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_SETSTATE, nState, 0L); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + int StepIt() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_STEPIT, 0, 0L)); + } +}; + +typedef CProgressBarCtrlT CProgressBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CHotKeyCtrl + +#ifndef _WIN32_WCE + +template +class CHotKeyCtrlT : public TBase +{ +public: +// Constructors + CHotKeyCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CHotKeyCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return HOTKEY_CLASS; + } + + DWORD GetHotKey() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L); + } + + void GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dw = (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L); + wVirtualKeyCode = LOBYTE(LOWORD(dw)); + wModifiers = HIBYTE(LOWORD(dw)); + } + + void SetHotKey(WORD wVirtualKeyCode, WORD wModifiers) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, HKM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0L); + } + + void SetRules(WORD wInvalidComb, WORD wModifiers) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, HKM_SETRULES, wInvalidComb, MAKELPARAM(wModifiers, 0)); + } +}; + +typedef CHotKeyCtrlT CHotKeyCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CAnimateCtrl + +#ifndef _WIN32_WCE + +template +class CAnimateCtrlT : public TBase +{ +public: +// Constructors + CAnimateCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CAnimateCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return ANIMATE_CLASS; + } + +// Operations + BOOL Open(ATL::_U_STRINGorID FileName) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, (LPARAM)FileName.m_lpstr); + } + + BOOL Play(UINT nFrom, UINT nTo, UINT nRep) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, nRep, MAKELPARAM(nFrom, nTo)); + } + + BOOL Stop() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_STOP, 0, 0L); + } + + BOOL Close() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, 0L); + } + + BOOL Seek(UINT nTo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, 0, MAKELPARAM(nTo, nTo)); + } + + // Vista only + BOOL IsPlaying() const + { +#ifndef ACM_ISPLAYING + const UINT ACM_ISPLAYING = (WM_USER+104); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_ISPLAYING, 0, 0L); + } +}; + +typedef CAnimateCtrlT CAnimateCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CRichEditCtrl + +#ifndef _WIN32_WCE + +#ifdef _UNICODE +#if (_RICHEDIT_VER == 0x0100) +#undef RICHEDIT_CLASS +#define RICHEDIT_CLASS L"RICHEDIT" +#endif // (_RICHEDIT_VER == 0x0100) +#endif // _UNICODE + +template +class CRichEditCtrlT : public TBase +{ +public: +// Constructors + CRichEditCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CRichEditCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return RICHEDIT_CLASS; + } + + static LPCTSTR GetLibraryName() + { +#if (_RICHEDIT_VER >= 0x0200) + return _T("RICHED20.DLL"); +#else + return _T("RICHED32.DLL"); +#endif + } + + int GetLineCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L); + } + + BOOL GetModify() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); + } + + void SetModify(BOOL bModified = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L); + } + + void GetRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect); + } + + DWORD GetOptions() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETOPTIONS, 0, 0L); + } + + DWORD SetOptions(WORD wOperation, DWORD dwOptions) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_SETOPTIONS, wOperation, dwOptions); + } + + // NOTE: first word in lpszBuffer must contain the size of the buffer! + int GetLine(int nIndex, LPTSTR lpszBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + *(LPWORD)lpszBuffer = (WORD)nMaxLength; + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + BOOL CanUndo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); + } + + BOOL CanPaste(UINT nFormat = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, nFormat, 0L); + } + + void GetSel(LONG& nStartChar, LONG& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + CHARRANGE cr = { 0, 0 }; + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + nStartChar = cr.cpMin; + nEndChar = cr.cpMax; + } + + void GetSel(CHARRANGE &cr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + } + + int SetSel(LONG nStartChar, LONG nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + CHARRANGE cr = { nStartChar, nEndChar }; + return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr); + } + + int SetSel(CHARRANGE &cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr); + } + + int SetSelAll() + { + return SetSel(0, -1); + } + + int SetSelNone() + { + return SetSel(-1, 0); + } + + DWORD GetDefaultCharFormat(CHARFORMAT& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf); + } + + DWORD GetSelectionCharFormat(CHARFORMAT& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf); + } + + DWORD GetEventMask() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETEVENTMASK, 0, 0L); + } + + LONG GetLimitText() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L); + } + + DWORD GetParaFormat(PARAFORMAT& pf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT); + return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); + } + +#if (_RICHEDIT_VER >= 0x0200) + LONG GetSelText(LPTSTR lpstrBuff) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff); + } +#else // !(_RICHEDIT_VER >= 0x0200) + // RichEdit 1.0 EM_GETSELTEXT is ANSI only + LONG GetSelText(LPSTR lpstrBuff) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff); + } +#endif // !(_RICHEDIT_VER >= 0x0200) + +#ifndef _ATL_NO_COM + BOOL GetSelTextBSTR(BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + CHARRANGE cr = { 0, 0 }; + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + +#if (_RICHEDIT_VER >= 0x0200) + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); + if(lpstrText == NULL) + return FALSE; + if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0) + return FALSE; + + bstrText = ::SysAllocString(T2W(lpstrText)); +#else // !(_RICHEDIT_VER >= 0x0200) + CTempBuffer buff; + LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); + if(lpstrText == NULL) + return FALSE; + if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0) + return FALSE; + + bstrText = ::SysAllocString(A2W(lpstrText)); +#endif // !(_RICHEDIT_VER >= 0x0200) + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + LONG GetSelText(_CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + + CHARRANGE cr = { 0, 0 }; + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + +#if (_RICHEDIT_VER >= 0x0200) + LONG lLen = 0; + LPTSTR lpstrText = strText.GetBufferSetLength(cr.cpMax - cr.cpMin); + if(lpstrText != NULL) + { + lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText); + strText.ReleaseBuffer(); + } +#else // !(_RICHEDIT_VER >= 0x0200) + CTempBuffer buff; + LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); + if(lpstrText == NULL) + return 0; + LONG lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText); + if(lLen == 0) + return 0; + + USES_CONVERSION; + strText = A2T(lpstrText); +#endif // !(_RICHEDIT_VER >= 0x0200) + + return lLen; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + WORD GetSelectionType() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (WORD)::SendMessage(m_hWnd, EM_SELECTIONTYPE, 0, 0L); + } + + COLORREF SetBackgroundColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 0, cr); + } + + COLORREF SetBackgroundColor() // sets to system background + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 1, 0); + } + + BOOL SetCharFormat(CHARFORMAT& cf, WORD wFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf); + } + + BOOL SetDefaultCharFormat(CHARFORMAT& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf); + } + + BOOL SetSelectionCharFormat(CHARFORMAT& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + } + + BOOL SetWordCharFormat(CHARFORMAT& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf); + } + + DWORD SetEventMask(DWORD dwEventMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_SETEVENTMASK, 0, dwEventMask); + } + + BOOL SetParaFormat(PARAFORMAT& pf) + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); + } + + BOOL SetTargetDevice(HDC hDC, int cxLineWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTARGETDEVICE, (WPARAM)hDC, cxLineWidth); + } + + int GetTextLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L); + } + + BOOL SetReadOnly(BOOL bReadOnly = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L); + } + + int GetFirstVisibleLine() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L); + } + + EDITWORDBREAKPROCEX GetWordBreakProcEx() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_GETWORDBREAKPROCEX, 0, 0L); + } + + EDITWORDBREAKPROCEX SetWordBreakProcEx(EDITWORDBREAKPROCEX pfnEditWordBreakProcEx) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_SETWORDBREAKPROCEX, 0, (LPARAM)pfnEditWordBreakProcEx); + } + + int GetTextRange(TEXTRANGE* pTextRange) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)pTextRange); + } + +#if (_RICHEDIT_VER >= 0x0200) + int GetTextRange(LONG nStartChar, LONG nEndChar, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TEXTRANGE tr = { 0 }; + tr.chrg.cpMin = nStartChar; + tr.chrg.cpMax = nEndChar; + tr.lpstrText = lpstrText; + return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); + } +#else // !(_RICHEDIT_VER >= 0x0200) + + int GetTextRange(LONG nStartChar, LONG nEndChar, LPSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TEXTRANGE tr = { 0 }; + tr.chrg.cpMin = nStartChar; + tr.chrg.cpMax = nEndChar; + tr.lpstrText = lpstrText; + return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); + } +#endif // !(_RICHEDIT_VER >= 0x0200) + +#if (_RICHEDIT_VER >= 0x0200) + DWORD GetDefaultCharFormat(CHARFORMAT2& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf); + } + + BOOL SetCharFormat(CHARFORMAT2& cf, WORD wFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf); + } + + BOOL SetDefaultCharFormat(CHARFORMAT2& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf); + } + + DWORD GetSelectionCharFormat(CHARFORMAT2& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf); + } + + BOOL SetSelectionCharFormat(CHARFORMAT2& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + } + + BOOL SetWordCharFormat(CHARFORMAT2& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf); + } + + DWORD GetParaFormat(PARAFORMAT2& pf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT2); + return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); + } + + BOOL SetParaFormat(PARAFORMAT2& pf) + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); + } + + TEXTMODE GetTextMode() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (TEXTMODE)::SendMessage(m_hWnd, EM_GETTEXTMODE, 0, 0L); + } + + BOOL SetTextMode(TEXTMODE enumTextMode) + { + ATLASSERT(::IsWindow(m_hWnd)); + return !(BOOL)::SendMessage(m_hWnd, EM_SETTEXTMODE, enumTextMode, 0L); + } + + UNDONAMEID GetUndoName() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETUNDONAME, 0, 0L); + } + + UNDONAMEID GetRedoName() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETREDONAME, 0, 0L); + } + + BOOL CanRedo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L); + } + + BOOL GetAutoURLDetect() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETAUTOURLDETECT, 0, 0L); + } + + BOOL SetAutoURLDetect(BOOL bAutoDetect = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return !(BOOL)::SendMessage(m_hWnd, EM_AUTOURLDETECT, bAutoDetect, 0L); + } + + // this method is deprecated, please use SetAutoURLDetect + BOOL EnableAutoURLDetect(BOOL bEnable = TRUE) { return SetAutoURLDetect(bEnable); } + + UINT SetUndoLimit(UINT uUndoLimit) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_SETUNDOLIMIT, uUndoLimit, 0L); + } + + void SetPalette(HPALETTE hPalette) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETPALETTE, (WPARAM)hPalette, 0L); + } + + int GetTextEx(GETTEXTEX* pGetTextEx, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)pGetTextEx, (LPARAM)lpstrText); + } + + int GetTextEx(LPTSTR lpstrText, int nTextLen, DWORD dwFlags = GT_DEFAULT, UINT uCodePage = CP_ACP, LPCSTR lpDefaultChar = NULL, LPBOOL lpUsedDefChar = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + GETTEXTEX gte = { 0 }; + gte.cb = nTextLen * sizeof(TCHAR); + gte.codepage = uCodePage; + gte.flags = dwFlags; + gte.lpDefaultChar = lpDefaultChar; + gte.lpUsedDefChar = lpUsedDefChar; + return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)>e, (LPARAM)lpstrText); + } + + int GetTextLengthEx(GETTEXTLENGTHEX* pGetTextLengthEx) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)pGetTextLengthEx, 0L); + } + + int GetTextLengthEx(DWORD dwFlags = GTL_DEFAULT, UINT uCodePage = CP_ACP) const + { + ATLASSERT(::IsWindow(m_hWnd)); + GETTEXTLENGTHEX gtle = { 0 }; + gtle.codepage = uCodePage; + gtle.flags = dwFlags; + return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)>le, 0L); + } +#endif // (_RICHEDIT_VER >= 0x0200) + +#if (_RICHEDIT_VER >= 0x0300) + int SetTextEx(SETTEXTEX* pSetTextEx, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)pSetTextEx, (LPARAM)lpstrText); + } + + int SetTextEx(LPCTSTR lpstrText, DWORD dwFlags = ST_DEFAULT, UINT uCodePage = CP_ACP) + { + ATLASSERT(::IsWindow(m_hWnd)); + SETTEXTEX ste = { 0 }; + ste.flags = dwFlags; + ste.codepage = uCodePage; + return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpstrText); + } + + int GetEditStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETEDITSTYLE, 0, 0L); + } + + int SetEditStyle(int nStyle, int nMask = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + if(nMask == -1) + nMask = nStyle; // set everything specified + return (int)::SendMessage(m_hWnd, EM_SETEDITSTYLE, nStyle, nMask); + } + + BOOL SetFontSize(int nFontSizeDelta) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nFontSizeDelta >= -1637 && nFontSizeDelta <= 1638); + return (BOOL)::SendMessage(m_hWnd, EM_SETFONTSIZE, nFontSizeDelta, 0L); + } + + void GetScrollPos(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpPoint != NULL); + ::SendMessage(m_hWnd, EM_GETSCROLLPOS, 0, (LPARAM)lpPoint); + } + + void SetScrollPos(LPPOINT lpPoint) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpPoint != NULL); + ::SendMessage(m_hWnd, EM_SETSCROLLPOS, 0, (LPARAM)lpPoint); + } + + BOOL GetZoom(int& nNum, int& nDen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETZOOM, (WPARAM)&nNum, (LPARAM)&nDen); + } + + BOOL SetZoom(int nNum, int nDen) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nNum >= 0 && nNum <= 64); + ATLASSERT(nDen >= 0 && nDen <= 64); + return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, nNum, nDen); + } + + BOOL SetZoomOff() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, 0, 0L); + } +#endif // (_RICHEDIT_VER >= 0x0300) + +// Operations + void LimitText(LONG nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EXLIMITTEXT, 0, nChars); + } + + int LineFromChar(LONG nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_EXLINEFROMCHAR, 0, nIndex); + } + + POINT PosFromChar(LONG nChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + POINT point = { 0, 0 }; + ::SendMessage(m_hWnd, EM_POSFROMCHAR, (WPARAM)&point, nChar); + return point; + } + + int CharFromPos(POINT pt) const + { + ATLASSERT(::IsWindow(m_hWnd)); + POINTL ptl = { pt.x, pt.y }; + return (int)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, (LPARAM)&ptl); + } + + void EmptyUndoBuffer() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L); + } + + int LineIndex(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L); + } + + int LineLength(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L); + } + + BOOL LineScroll(int nLines, int nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines); + } + + void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText); + } + + void SetRect(LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect); + } + + BOOL DisplayBand(LPRECT pDisplayRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_DISPLAYBAND, 0, (LPARAM)pDisplayRect); + } + + LONG FindText(DWORD dwFlags, FINDTEXT& ft) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE) + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTW, dwFlags, (LPARAM)&ft); +#else + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXT, dwFlags, (LPARAM)&ft); +#endif + } + + LONG FindText(DWORD dwFlags, FINDTEXTEX& ft) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE) + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEXW, dwFlags, (LPARAM)&ft); +#else + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEX, dwFlags, (LPARAM)&ft); +#endif + } + + LONG FormatRange(FORMATRANGE& fr, BOOL bDisplay = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)&fr); + } + + LONG FormatRange(FORMATRANGE* pFormatRange, BOOL bDisplay = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)pFormatRange); + } + + void HideSelection(BOOL bHide = TRUE, BOOL bChangeStyle = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_HIDESELECTION, bHide, bChangeStyle); + } + + void PasteSpecial(UINT uClipFormat, DWORD dwAspect = 0, HMETAFILE hMF = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + REPASTESPECIAL reps = { dwAspect, (DWORD_PTR)hMF }; + ::SendMessage(m_hWnd, EM_PASTESPECIAL, uClipFormat, (LPARAM)&reps); + } + + void RequestResize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REQUESTRESIZE, 0, 0L); + } + + LONG StreamIn(UINT uFormat, EDITSTREAM& es) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, uFormat, (LPARAM)&es); + } + + LONG StreamOut(UINT uFormat, EDITSTREAM& es) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, uFormat, (LPARAM)&es); + } + + DWORD FindWordBreak(int nCode, LONG nStartChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_FINDWORDBREAK, nCode, nStartChar); + } + + // Additional operations + void ScrollCaret() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + int InsertText(long nInsertAfterChar, LPCTSTR lpstrText, BOOL bCanUndo = FALSE) + { + int nRet = SetSel(nInsertAfterChar, nInsertAfterChar); + ReplaceSel(lpstrText, bCanUndo); + return nRet; + } + + int AppendText(LPCTSTR lpstrText, BOOL bCanUndo = FALSE) + { + return InsertText(GetWindowTextLength(), lpstrText, bCanUndo); + } + + // Clipboard operations + BOOL Undo() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L); + } + + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } + + // OLE support + IRichEditOle* GetOleInterface() const + { + ATLASSERT(::IsWindow(m_hWnd)); + IRichEditOle *pRichEditOle = NULL; + ::SendMessage(m_hWnd, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); + return pRichEditOle; + } + + BOOL SetOleCallback(IRichEditOleCallback* pCallback) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETOLECALLBACK, 0, (LPARAM)pCallback); + } + +#if (_RICHEDIT_VER >= 0x0200) + BOOL Redo() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_REDO, 0, 0L); + } + + void StopGroupTyping() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_STOPGROUPTYPING, 0, 0L); + } + + void ShowScrollBar(int nBarType, BOOL bVisible = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SHOWSCROLLBAR, nBarType, bVisible); + } +#endif // (_RICHEDIT_VER >= 0x0200) + +#if (_RICHEDIT_VER >= 0x0300) + BOOL SetTabStops(int nTabStops, LPINT rgTabStops) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); + } + + BOOL SetTabStops() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L); + } + + BOOL SetTabStops(const int& cxEachStop) // takes an 'int' + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); + } +#endif // (_RICHEDIT_VER >= 0x0300) +}; + +typedef CRichEditCtrlT CRichEditCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CRichEditCommands - message handlers for standard EDIT commands + +#ifndef _WIN32_WCE + +// Chain to CRichEditCommands message map. Your class must also derive from CRichEditCtrl. +// Example: +// class CMyRichEdit : public CWindowImpl, +// public CRichEditCommands +// { +// public: +// BEGIN_MSG_MAP(CMyRichEdit) +// // your handlers... +// CHAIN_MSG_MAP_ALT(CRichEditCommands, 1) +// END_MSG_MAP() +// // other stuff... +// }; + +template +class CRichEditCommands : public CEditCommands< T > +{ +public: + BEGIN_MSG_MAP(CRichEditCommands< T >) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR, CEditCommands< T >::OnEditClear) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, CEditCommands< T >::OnEditClearAll) + COMMAND_ID_HANDLER(ID_EDIT_COPY, CEditCommands< T >::OnEditCopy) + COMMAND_ID_HANDLER(ID_EDIT_CUT, CEditCommands< T >::OnEditCut) + COMMAND_ID_HANDLER(ID_EDIT_PASTE, CEditCommands< T >::OnEditPaste) + COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, CEditCommands< T >::OnEditSelectAll) + COMMAND_ID_HANDLER(ID_EDIT_UNDO, CEditCommands< T >::OnEditUndo) +#if (_RICHEDIT_VER >= 0x0200) + COMMAND_ID_HANDLER(ID_EDIT_REDO, OnEditRedo) +#endif // (_RICHEDIT_VER >= 0x0200) + END_MSG_MAP() + +#if (_RICHEDIT_VER >= 0x0200) + LRESULT OnEditRedo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Redo(); + return 0; + } +#endif // (_RICHEDIT_VER >= 0x0200) + +// State (update UI) helpers + BOOL CanCut() const + { return HasSelection(); } + + BOOL CanCopy() const + { return HasSelection(); } + + BOOL CanClear() const + { return HasSelection(); } + +// Implementation + BOOL HasSelection() const + { + const T* pT = static_cast(this); + return (pT->GetSelectionType() != SEL_EMPTY); + } +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CDragListBox + +#ifndef _WIN32_WCE + +template +class CDragListBoxT : public CListBoxT< TBase > +{ +public: +// Constructors + CDragListBoxT(HWND hWnd = NULL) : CListBoxT< TBase >(hWnd) + { } + + CDragListBoxT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + if(hWnd != NULL) + MakeDragList(); + return hWnd; + } + +// Operations + BOOL MakeDragList() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); + return ::MakeDragList(m_hWnd); + } + + int LBItemFromPt(POINT pt, BOOL bAutoScroll = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::LBItemFromPt(m_hWnd, pt, bAutoScroll); + } + + void DrawInsert(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::DrawInsert(GetParent(), m_hWnd, nItem); + } + + static UINT GetDragListMessage() + { + static UINT uDragListMessage = 0; + if(uDragListMessage == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDragListBox::GetDragListMessage.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uDragListMessage == 0) + uDragListMessage = ::RegisterWindowMessage(DRAGLISTMSGSTRING); + + lock.Unlock(); + } + ATLASSERT(uDragListMessage != 0); + return uDragListMessage; + } +}; + +typedef CDragListBoxT CDragListBox; + +template +class CDragListNotifyImpl +{ +public: + BEGIN_MSG_MAP(CDragListNotifyImpl< T >) + MESSAGE_HANDLER(CDragListBox::GetDragListMessage(), OnDragListNotify) + END_MSG_MAP() + + LRESULT OnDragListNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + uMsg; // avoid level 4 warning + ATLASSERT(uMsg == CDragListBox::GetDragListMessage()); + T* pT = static_cast(this); + LPDRAGLISTINFO lpDragListInfo = (LPDRAGLISTINFO)lParam; + LRESULT lRet = 0; + switch(lpDragListInfo->uNotification) + { + case DL_BEGINDRAG: + lRet = (LPARAM)pT->OnBeginDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + case DL_CANCELDRAG: + pT->OnCancelDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + case DL_DRAGGING: + lRet = (LPARAM)pT->OnDragging((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + case DL_DROPPED: + pT->OnDropped((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("Unknown DragListBox notification\n")); + bHandled = FALSE; // don't handle it + break; + } + return lRet; + } + +// Overrideables + BOOL OnBeginDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + return TRUE; // allow dragging + } + + void OnCancelDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + // nothing to do + } + + int OnDragging(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + return 0; // don't change cursor + } + + void OnDropped(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + // nothing to do + } +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CReBarCtrl + +template +class CReBarCtrlT : public TBase +{ +public: +// Constructors + CReBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CReBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return REBARCLASSNAME; + } + + UINT GetBandCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETBANDCOUNT, 0, 0L); + } + + BOOL GetBandInfo(int nBand, LPREBARBANDINFO lprbbi) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETBANDINFO, nBand, (LPARAM)lprbbi); + } + + BOOL SetBandInfo(int nBand, LPREBARBANDINFO lprbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETBANDINFO, nBand, (LPARAM)lprbbi); + } + + BOOL GetBarInfo(LPREBARINFO lprbi) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)lprbi); + } + + BOOL SetBarInfo(LPREBARINFO lprbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)lprbi); + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + REBARINFO rbi = { 0 }; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = RBIM_IMAGELIST; + if( (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)&rbi) == FALSE ) return CImageList(); + return CImageList(rbi.himl); + } + + BOOL SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + REBARINFO rbi = { 0 }; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = RBIM_IMAGELIST; + rbi.himl = hImageList; + return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)&rbi); + } + + UINT GetRowCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETROWCOUNT, 0, 0L); + } + + UINT GetRowHeight(int nBand) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETROWHEIGHT, nBand, 0L); + } + +#if (_WIN32_IE >= 0x0400) + COLORREF GetTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_GETTEXTCOLOR, 0, 0L); + } + + COLORREF SetTextColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_SETTEXTCOLOR, 0, (LPARAM)clr); + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_GETBKCOLOR, 0, 0L); + } + + COLORREF SetBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_SETBKCOLOR, 0, (LPARAM)clr); + } + + UINT GetBarHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETBARHEIGHT, 0, 0L); + } + + BOOL GetRect(int nBand, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETRECT, nBand, (LPARAM)lpRect); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, RB_GETTOOLTIPS, 0, 0L)); + } + + void SetToolTips(HWND hwndToolTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_SETTOOLTIPS, (WPARAM)hwndToolTip, 0L); + } +#endif // !_WIN32_WCE + + void GetBandBorders(int nBand, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpRect != NULL); + ::SendMessage(m_hWnd, RB_GETBANDBORDERS, nBand, (LPARAM)lpRect); + } + +#ifndef _WIN32_WCE + BOOL GetColorScheme(LPCOLORSCHEME lpColorScheme) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpColorScheme != NULL); + return (BOOL)::SendMessage(m_hWnd, RB_GETCOLORSCHEME, 0, (LPARAM)lpColorScheme); + } + + void SetColorScheme(LPCOLORSCHEME lpColorScheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpColorScheme != NULL); + ::SendMessage(m_hWnd, RB_SETCOLORSCHEME, 0, (LPARAM)lpColorScheme); + } + + HPALETTE GetPalette() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HPALETTE)::SendMessage(m_hWnd, RB_GETPALETTE, 0, 0L); + } + + HPALETTE SetPalette(HPALETTE hPalette) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HPALETTE)::SendMessage(m_hWnd, RB_SETPALETTE, 0, (LPARAM)hPalette); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0501) + // requires uxtheme.h to be included to use MARGINS struct +#ifndef _UXTHEME_H_ + typedef struct _MARGINS* PMARGINS; +#endif // !_UXTHEME_H_ + void GetBandMargins(PMARGINS pMargins) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_GETBANDMARGINS, 0, (LPARAM)pMargins); + } + + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_IE >= 0x0600) + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, RB_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, RB_SETEXTENDEDSTYLE, dwMask, dwStyle); + } +#endif // (_WIN32_IE >= 0x0600) + +// Operations + BOOL InsertBand(int nBand, LPREBARBANDINFO lprbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_INSERTBAND, nBand, (LPARAM)lprbbi); + } + + BOOL AddBand(LPREBARBANDINFO lprbbi) + { + return InsertBand(-1, lprbbi); + } + + BOOL DeleteBand(int nBand) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_DELETEBAND, nBand, 0L); + } + + ATL::CWindow SetNotifyWnd(HWND hWnd) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, RB_SETPARENT, (WPARAM)hWnd, 0L)); + } + +#if (_WIN32_IE >= 0x0400) + void BeginDrag(int nBand, DWORD dwPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, dwPos); + } + + void BeginDrag(int nBand, int xPos, int yPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, MAKELPARAM(xPos, yPos)); + } + + void EndDrag() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_ENDDRAG, 0, 0L); + } + + void DragMove(DWORD dwPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, dwPos); + } + + void DragMove(int xPos, int yPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, MAKELPARAM(xPos, yPos)); + } + +#ifndef _WIN32_WCE + void GetDropTarget(IDropTarget** ppDropTarget) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_GETDROPTARGET, 0, (LPARAM)ppDropTarget); + } +#endif // !_WIN32_WCE + + void MaximizeBand(int nBand, BOOL bIdeal = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_MAXIMIZEBAND, nBand, bIdeal); + } + + void MinimizeBand(int nBand) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_MINIMIZEBAND, nBand, 0L); + } + + BOOL SizeToRect(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SIZETORECT, 0, (LPARAM)lpRect); + } + + int IdToIndex(UINT uBandID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, RB_IDTOINDEX, uBandID, 0L); + } + + int HitTest(LPRBHITTESTINFO lprbht) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, RB_HITTEST, 0, (LPARAM)lprbht); + } + + BOOL ShowBand(int nBand, BOOL bShow) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SHOWBAND, nBand, bShow); + } + +#ifndef _WIN32_WCE + BOOL MoveBand(int nBand, int nNewPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nNewPos >= 0 && nNewPos <= ((int)GetBandCount() - 1)); + return (BOOL)::SendMessage(m_hWnd, RB_MOVEBAND, nBand, nNewPos); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + void PushChevron(int nBand, LPARAM lAppValue) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_PUSHCHEVRON, nBand, lAppValue); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +// Extra operations +#if (_WIN32_IE >= 0x0400) + void LockBands(bool bLock) + { + int nBandCount = GetBandCount(); + for(int i =0; i < nBandCount; i++) + { + REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() }; + rbbi.fMask = RBBIM_STYLE; + BOOL bRet = GetBandInfo(i, &rbbi); + ATLASSERT(bRet); + + if((rbbi.fStyle & RBBS_GRIPPERALWAYS) == 0) + { + rbbi.fStyle |= RBBS_GRIPPERALWAYS; + bRet = SetBandInfo(i, &rbbi); + ATLASSERT(bRet); + rbbi.fStyle &= ~RBBS_GRIPPERALWAYS; + } + + if(bLock) + rbbi.fStyle |= RBBS_NOGRIPPER; + else + rbbi.fStyle &= ~RBBS_NOGRIPPER; + + bRet = SetBandInfo(i, &rbbi); + ATLASSERT(bRet); + } + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0600) + BOOL SetBandWidth(int nBand, int cxWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETBANDWIDTH, nBand, cxWidth); + } +#endif // (_WIN32_WINNT >= 0x0600) +}; + +typedef CReBarCtrlT CReBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CComboBoxEx + +#ifndef _WIN32_WCE + +template +class CComboBoxExT : public CComboBoxT< TBase > +{ +public: +// Constructors + CComboBoxExT(HWND hWnd = NULL) : CComboBoxT< TBase >(hWnd) + { } + + CComboBoxExT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_COMBOBOXEX; + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_GETIMAGELIST, 0, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_SETIMAGELIST, 0, (LPARAM)hImageList)); + } + +#if (_WIN32_IE >= 0x0400) + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, CBEM_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, CBEM_SETEXTENDEDSTYLE, dwExMask, dwExStyle); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0501) + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CBEM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + int InsertItem(const COMBOBOXEXITEM* lpcCBItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)lpcCBItem); + } + + int InsertItem(UINT nMask, int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, + int iIndent, int iOverlay, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = nMask; + cbex.iItem = nIndex; + cbex.pszText = (LPTSTR) lpszItem; + cbex.iImage = nImage; + cbex.iSelectedImage = nSelImage; + cbex.iIndent = iIndent; + cbex.iOverlay = iOverlay; + cbex.lParam = lParam; + return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex); + } + + int InsertItem(int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT | CBEIF_LPARAM; + cbex.iItem = nIndex; + cbex.pszText = (LPTSTR) lpszItem; + cbex.iImage = nImage; + cbex.iSelectedImage = nSelImage; + cbex.iIndent = iIndent; + cbex.lParam = lParam; + return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex); + } + + int AddItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, int iOverlay, LPARAM lParam) + { + return InsertItem(nMask, -1, lpszItem, nImage, nSelImage, iIndent, iOverlay, lParam); + } + + int AddItem(LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0) + { + return InsertItem(-1, lpszItem, nImage, nSelImage, iIndent, lParam); + } + + int DeleteItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CBEM_DELETEITEM, nIndex, 0L); + } + + BOOL GetItem(PCOMBOBOXEXITEM pCBItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)pCBItem); + } + + BOOL SetItem(const COMBOBOXEXITEM* lpcCBItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)lpcCBItem); + } + + int SetItem(int nIndex, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, + int iIndent, int iOverlay, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = nMask; + cbex.iItem = nIndex; + cbex.pszText = (LPTSTR) lpszItem; + cbex.iImage = nImage; + cbex.iSelectedImage = nSelImage; + cbex.iIndent = iIndent; + cbex.iOverlay = iOverlay; + cbex.lParam = lParam; + return (int)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)&cbex); + } + + BOOL GetItemText(int nIndex, LPTSTR lpszItem, int nLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpszItem != NULL); + + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT; + cbex.iItem = nIndex; + cbex.pszText = lpszItem; + cbex.cchTextMax = nLen; + + return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); + } + +#ifndef _ATL_NO_COM + BOOL GetItemText(int nIndex, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT; + cbex.iItem = nIndex; + + LPTSTR lpstrText = NULL; + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + lpstrText[0] = NULL; + cbex.pszText = lpstrText; + cbex.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); + if(!bRet || (lstrlen(cbex.pszText) < nLen - 1)) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(bRet) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetItemText(int nIndex, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT; + cbex.iItem = nIndex; + + strText.Empty(); + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + cbex.pszText = strText.GetBufferSetLength(nLen); + if(cbex.pszText == NULL) + { + bRet = FALSE; + break; + } + cbex.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); + if(!bRet || (lstrlen(cbex.pszText) < nLen - 1)) + break; + } + strText.ReleaseBuffer(); + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL SetItemText(int nIndex, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(nIndex, CBEIF_TEXT, lpszItem, 0, 0, 0, 0, 0); + } + + CComboBox GetComboCtrl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CComboBox((HWND)::SendMessage(m_hWnd, CBEM_GETCOMBOCONTROL, 0, 0L)); + } + + CEdit GetEditCtrl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, CBEM_GETEDITCONTROL, 0, 0L)); + } + + BOOL HasEditChanged() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_HASEDITCHANGED, 0, 0L); + } + +// Non-functional + int AddString(LPCTSTR /*lpszItem*/) + { + ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem + return 0; + } + + int InsertString(int /*nIndex*/, LPCTSTR /*lpszString*/) + { + ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem + return 0; + } + + int Dir(UINT /*attr*/, LPCTSTR /*lpszWildCard*/) + { + ATLASSERT(FALSE); // Not available in CComboBoxEx + return 0; + } + + int FindString(int /*nStartAfter*/, LPCTSTR /*lpszString*/) const + { + ATLASSERT(FALSE); // Not available in CComboBoxEx; try FindStringExact + return 0; + } +}; + +typedef CComboBoxExT CComboBoxEx; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CMonthCalendarCtrl + +template +class CMonthCalendarCtrlT : public TBase +{ +public: +// Constructors + CMonthCalendarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CMonthCalendarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return MONTHCAL_CLASS; + } + + COLORREF GetColor(int nColorType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, MCM_GETCOLOR, nColorType, 0L); + } + + COLORREF SetColor(int nColorType, COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, MCM_SETCOLOR, nColorType, clr); + } + + BOOL GetCurSel(LPSYSTEMTIME lpSysTime) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM)lpSysTime); + } + + BOOL SetCurSel(LPSYSTEMTIME lpSysTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETCURSEL, 0, (LPARAM)lpSysTime); + } + + int GetFirstDayOfWeek(BOOL* pbLocaleVal = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_GETFIRSTDAYOFWEEK, 0, 0L); + if(pbLocaleVal != NULL) + *pbLocaleVal = (BOOL)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + int SetFirstDayOfWeek(int nDay, BOOL* pbLocaleVal = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_SETFIRSTDAYOFWEEK, 0, nDay); + if(pbLocaleVal != NULL) + *pbLocaleVal = (BOOL)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + int GetMaxSelCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMAXSELCOUNT, 0, 0L); + } + + BOOL SetMaxSelCount(int nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETMAXSELCOUNT, nMax, 0L); + } + + int GetMonthDelta() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMONTHDELTA, 0, 0L); + } + + int SetMonthDelta(int nDelta) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_SETMONTHDELTA, nDelta, 0L); + } + + DWORD GetRange(LPSYSTEMTIME lprgSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM)lprgSysTimeArray); + } + + BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETRANGE, dwFlags, (LPARAM)lprgSysTimeArray); + } + + BOOL GetSelRange(LPSYSTEMTIME lprgSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETSELRANGE, 0, (LPARAM)lprgSysTimeArray); + } + + BOOL SetSelRange(LPSYSTEMTIME lprgSysTimeArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETSELRANGE, 0, (LPARAM)lprgSysTimeArray); + } + + BOOL GetToday(LPSYSTEMTIME lpSysTime) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETTODAY, 0, (LPARAM)lpSysTime); + } + + void SetToday(LPSYSTEMTIME lpSysTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SETTODAY, 0, (LPARAM)lpSysTime); + } + + BOOL GetMinReqRect(LPRECT lpRectInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETMINREQRECT, 0, (LPARAM)lpRectInfo); + } + + int GetMaxTodayWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMAXTODAYWIDTH, 0, 0L); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + DWORD GetCurrentView() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_GETCURRENTVIEW, 0, 0L); + } + + BOOL SetCurrentView(DWORD dwView) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETCURRENTVIEW, 0, dwView); + } + + DWORD GetCalendarCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_GETCALENDARCOUNT, 0, 0L); + } + + BOOL GetCalendarGridInfo(PMCGRIDINFO pGridInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETCALENDARGRIDINFO, 0, (LPARAM)pGridInfo); + } + + CALID GetCALID() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (CALID)::SendMessage(m_hWnd, MCM_GETCALID, 0, 0L); + } + + void SetCALID(CALID calid) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SETCALID, (LPARAM)calid, 0L); + } + + int GetCalendarBorder() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETCALENDARBORDER, 0, 0L); + } + + void SetCalendarBorder(int cxyBorder, BOOL bSet = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SETCALENDARBORDER, (WPARAM)bSet, (LPARAM)cxyBorder); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + +// Operations + int GetMonthRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMONTHRANGE, dwFlags, (LPARAM)lprgSysTimeArray); + } + + BOOL SetDayState(int nMonths, LPMONTHDAYSTATE lpDayStateArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETDAYSTATE, nMonths, (LPARAM)lpDayStateArray); + } + + DWORD HitTest(PMCHITTESTINFO pMCHitTest) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_HITTEST, 0, (LPARAM)pMCHitTest); + } + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + void SizeRectToMin(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SIZERECTTOMIN, 0, (LPARAM)lpRect); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) +}; + +typedef CMonthCalendarCtrlT CMonthCalendarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CDateTimePickerCtrl + +template +class CDateTimePickerCtrlT : public TBase +{ +public: +// Constructors + CDateTimePickerCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CDateTimePickerCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Operations + static LPCTSTR GetWndClassName() + { + return DATETIMEPICK_CLASS; + } + + BOOL SetFormat(LPCTSTR lpszFormat) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_SETFORMAT, 0, (LPARAM)lpszFormat); + } + + COLORREF GetMonthCalColor(int nColorType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, DTM_GETMCCOLOR, nColorType, 0L); + } + + COLORREF SetMonthCalColor(int nColorType, COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, DTM_SETMCCOLOR, nColorType, clr); + } + + DWORD GetRange(LPSYSTEMTIME lpSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_GETRANGE, 0, (LPARAM)lpSysTimeArray); + } + + BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lpSysTimeArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_SETRANGE, dwFlags, (LPARAM)lpSysTimeArray); + } + + DWORD GetSystemTime(LPSYSTEMTIME lpSysTime) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)lpSysTime); + } + + BOOL SetSystemTime(DWORD dwFlags, LPSYSTEMTIME lpSysTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, dwFlags, (LPARAM)lpSysTime); + } + + CMonthCalendarCtrl GetMonthCal() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CMonthCalendarCtrl((HWND)::SendMessage(m_hWnd, DTM_GETMONTHCAL, 0, 0L)); + } + +#if (_WIN32_IE >= 0x0400) + CFontHandle GetMonthCalFont() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CFontHandle((HFONT)::SendMessage(m_hWnd, DTM_GETMCFONT, 0, 0L)); + } + + void SetMonthCalFont(HFONT hFont, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_SETMCFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0)); + } +#endif // (_WIN32_IE >= 0x0400) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + DWORD GetMonthCalStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_GETMCSTYLE, 0, 0L); + } + + DWORD SetMonthCalStyle(DWORD dwStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_SETMCSTYLE, 0, (LPARAM)dwStyle); + } + + void GetDateTimePickerInfo(LPDATETIMEPICKERINFO lpPickerInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_GETDATETIMEPICKERINFO, 0, (LPARAM)lpPickerInfo); + } + + BOOL GetIdealSize(LPSIZE lpSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_GETIDEALSIZE, 0, (LPARAM)lpSize); + } + + void CloseMonthCal() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_CLOSEMONTHCAL, 0, 0L); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) +}; + +typedef CDateTimePickerCtrlT CDateTimePickerCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CFlatScrollBarImpl - support for flat scroll bars + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +template +class CFlatScrollBarImpl +{ +public: +// Initialization + BOOL FlatSB_Initialize() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::InitializeFlatSB(pT->m_hWnd); + } + + HRESULT FlatSB_Uninitialize() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::UninitializeFlatSB(pT->m_hWnd); + } + +// Flat scroll bar properties + BOOL FlatSB_GetScrollProp(UINT uIndex, LPINT lpnValue) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollProp(pT->m_hWnd, uIndex, lpnValue); + } + + BOOL FlatSB_SetScrollProp(UINT uIndex, int nValue, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollProp(pT->m_hWnd, uIndex, nValue, bRedraw); + } + +// Attributes + int FlatSB_GetScrollPos(int nBar) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollPos(pT->m_hWnd, nBar); + } + + int FlatSB_SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollPos(pT->m_hWnd, nBar, nPos, bRedraw); + } + + BOOL FlatSB_GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollRange(pT->m_hWnd, nBar, lpMinPos, lpMaxPos); + } + + BOOL FlatSB_SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollRange(pT->m_hWnd, nBar, nMinPos, nMaxPos, bRedraw); + } + + BOOL FlatSB_GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo); + } + + int FlatSB_SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo, bRedraw); + } + +// Operations + BOOL FlatSB_ShowScrollBar(UINT nBar, BOOL bShow = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_ShowScrollBar(pT->m_hWnd, nBar, bShow); + } + + BOOL FlatSB_EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_EnableScrollBar(pT->m_hWnd, uSBFlags, uArrowFlags); + } +}; + +template +class CFlatScrollBarT : public TBase, public CFlatScrollBarImpl > +{ +public: + CFlatScrollBarT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CFlatScrollBarT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } +}; + +typedef CFlatScrollBarT CFlatScrollBar; + +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CIPAddressCtrl + +#if (_WIN32_IE >= 0x0400) + +template +class CIPAddressCtrlT : public TBase +{ +public: +// Constructors + CIPAddressCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CIPAddressCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Atteributes + static LPCTSTR GetWndClassName() + { + return WC_IPADDRESS; + } + + BOOL IsBlank() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, IPM_ISBLANK, 0, 0L); + } + + int GetAddress(LPDWORD lpdwAddress) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, IPM_GETADDRESS, 0, (LPARAM)lpdwAddress); + } + + void SetAddress(DWORD dwAddress) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETADDRESS, 0, dwAddress); + } + + void ClearAddress() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_CLEARADDRESS, 0, 0L); + } + + void SetRange(int nField, WORD wRange) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETRANGE, nField, wRange); + } + + void SetRange(int nField, BYTE nMin, BYTE nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETRANGE, nField, MAKEIPRANGE(nMin, nMax)); + } + + void SetFocus(int nField) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETFOCUS, nField, 0L); + } +}; + +typedef CIPAddressCtrlT CIPAddressCtrl; + +#endif // (_WIN32_IE >= 0x0400) + + +/////////////////////////////////////////////////////////////////////////////// +// CPagerCtrl + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +template +class CPagerCtrlT : public TBase +{ +public: +// Constructors + CPagerCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CPagerCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_PAGESCROLLER; + } + + int GetButtonSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_GETBUTTONSIZE, 0, 0L); + } + + int SetButtonSize(int nButtonSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_SETBUTTONSIZE, 0, nButtonSize); + } + + DWORD GetButtonState(int nButton) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nButton == PGB_TOPORLEFT || nButton == PGB_BOTTOMORRIGHT); + return (DWORD)::SendMessage(m_hWnd, PGM_GETBUTTONSTATE, 0, nButton); + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PGM_GETBKCOLOR, 0, 0L); + } + + COLORREF SetBkColor(COLORREF clrBk) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PGM_SETBKCOLOR, 0, (LPARAM)clrBk); + } + + int GetBorder() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_GETBORDER, 0, 0L); + } + + int SetBorder(int nBorderSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_SETBORDER, 0, nBorderSize); + } + + int GetPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_GETPOS, 0, 0L); + } + + int SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_SETPOS, 0, nPos); + } + +// Operations + void SetChild(HWND hWndChild) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PGM_SETCHILD, 0, (LPARAM)hWndChild); + } + + void ForwardMouse(BOOL bForward = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PGM_FORWARDMOUSE, bForward, 0L); + } + + void RecalcSize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PGM_RECALCSIZE, 0, 0L); + } + + void GetDropTarget(IDropTarget** ppDropTarget) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(ppDropTarget != NULL); + ::SendMessage(m_hWnd, PGM_GETDROPTARGET, 0, (LPARAM)ppDropTarget); + } +}; + +typedef CPagerCtrlT CPagerCtrl; + +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CLinkCtrl - Windows SYSLINK control + +#if (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE) + +template +class CLinkCtrlT : public TBase +{ +public: +// Constructors + CLinkCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CLinkCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { +#ifdef _UNICODE + return WC_LINK; +#else // !_UNICODE + return "SysLink"; +#endif // !_UNICODE + } + + int GetIdealHeight(int cxMaxWidth = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LM_GETIDEALHEIGHT, cxMaxWidth, 0L); + } + + BOOL GetItem(PLITEM pLItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LM_GETITEM, 0, (LPARAM)pLItem); + } + + BOOL SetItem(PLITEM pLItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LM_SETITEM, 0, (LPARAM)pLItem); + } + + // Vista only + int GetIdealSize(SIZE& size, int cxMaxWidth = 0) const + { +#ifndef LM_GETIDEALSIZE + const UINT LM_GETIDEALSIZE = LM_GETIDEALHEIGHT; +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LM_GETIDEALSIZE, cxMaxWidth, (LPARAM)&size); + } + +// Operations + BOOL HitTest(PLHITTESTINFO pLHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LM_HITTEST, 0, (LPARAM)pLHitTestInfo); + } +}; + +typedef CLinkCtrlT CLinkCtrl; + +#endif // (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CCustomDraw - MI class for custom-draw support + +template +class CCustomDraw +{ +public: +#if (_ATL_VER < 0x0700) + BOOL m_bHandledCD; + + BOOL IsMsgHandled() const + { + return m_bHandledCD; + } + + void SetMsgHandled(BOOL bHandled) + { + m_bHandledCD = bHandled; + } +#endif // !(_ATL_VER < 0x0700) + +// Message map and handlers + BEGIN_MSG_MAP(CCustomDraw< T >) + NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + ALT_MSG_MAP(1) + REFLECTED_NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + END_MSG_MAP() + +// message handler + LRESULT OnCustomDraw(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->SetMsgHandled(TRUE); + LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW)pnmh; + DWORD dwRet = 0; + switch(lpNMCustomDraw->dwDrawStage) + { + case CDDS_PREPAINT: + dwRet = pT->OnPrePaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_POSTPAINT: + dwRet = pT->OnPostPaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_PREERASE: + dwRet = pT->OnPreErase(idCtrl, lpNMCustomDraw); + break; + case CDDS_POSTERASE: + dwRet = pT->OnPostErase(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPREPAINT: + dwRet = pT->OnItemPrePaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPOSTPAINT: + dwRet = pT->OnItemPostPaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPREERASE: + dwRet = pT->OnItemPreErase(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPOSTERASE: + dwRet = pT->OnItemPostErase(idCtrl, lpNMCustomDraw); + break; +#if (_WIN32_IE >= 0x0400) + case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): + dwRet = pT->OnSubItemPrePaint(idCtrl, lpNMCustomDraw); + break; +#endif // (_WIN32_IE >= 0x0400) + default: + pT->SetMsgHandled(FALSE); + break; + } + bHandled = pT->IsMsgHandled(); + return dwRet; + } + +// Overrideables + DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + +#if (_WIN32_IE >= 0x0400) + DWORD OnSubItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } +#endif // (_WIN32_IE >= 0x0400) +}; + + +// --- Windows CE common controls --- + +#ifdef _WIN32_WCE + +/////////////////////////////////////////////////////////////////////////////// +// CCECommandBarCtrl + +template +class CCECommandBarCtrlT : public TBase +{ +public: +// Constructors + CCECommandBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) { } + + CCECommandBarCtrlT< TBase >& operator=(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + BOOL IsVisible() const + { + return IsWindowVisible(); + } + + int GetHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_Height(m_hWnd); + } + + HMENU GetMenu(WORD wButton) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_GetMenu(m_hWnd, wButton); + } + +// Operations + HWND Create(HWND hWndParent, int nCmdBarID) + { + m_hWnd = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), hWndParent, nCmdBarID); + ATLASSERT(::IsWindow(m_hWnd)); + return m_hWnd; + } + + void Destroy() + { + DestroyWindow(); + } + + BOOL Show(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_Show(m_hWnd, bShow); + } + + BOOL DrawMenuBar(WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_DrawMenuBar(m_hWnd, wButton); + } + + BOOL AddAdornments(DWORD dwFlags = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_AddAdornments(m_hWnd, dwFlags, 0); + } + + int AddBitmap(int nBitmapID, int nNumImages) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_AddBitmap(m_hWnd, ModuleHelper::GetResourceInstance(), nBitmapID, nNumImages, 16, 16); + } + + BOOL AddButtons(UINT uNumButtons, LPTBBUTTON lpButtons) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBar_AddButtons(m_hWnd, uNumButtons, lpButtons); + } + + BOOL AddToolTips(UINT uNumToolTips, LPTSTR lpToolTips) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBar_AddToolTips(m_hWnd, uNumToolTips, lpToolTips); + } + + BOOL InsertButton(int nButton, LPTBBUTTON lpButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBar_InsertButton(m_hWnd, nButton, lpButton); + } + + HWND InsertComboBox(int nWidth, UINT dwStyle, WORD wComboBoxID, WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_InsertComboBox(m_hWnd, ModuleHelper::GetModuleInstance(), nWidth, dwStyle, wComboBoxID, wButton); + } + + BOOL InsertMenubar(WORD wMenuID, WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_InsertMenubar(m_hWnd, ModuleHelper::GetResourceInstance(), wMenuID, wButton); + } + + BOOL InsertMenubarEx(ATL::_U_STRINGorID menu, WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_InsertMenubarEx(m_hWnd, ModuleHelper::GetResourceInstance(), (LPTSTR)menu.m_lpstr, wButton); + } + + BOOL IsCommandBarMessage(LPMSG lpMsg) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::IsCommandBarMessage(m_hWnd, lpMsg); + } +}; + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC MenuBar + typedef CCECommandBarCtrlT CMenuBarCtrl; +#else + typedef CCECommandBarCtrlT CCECommandBarCtrl; +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + +/////////////////////////////////////////////////////////////////////////////// +// CCECommandBandsCtrl + +template +class CCECommandBandsCtrlT : public TBase +{ +public: +// Constructors + CCECommandBandsCtrlT(HWND hWnd = NULL) : TBase(hWnd) { } + + CCECommandBandsCtrlT< TBase >& operator=(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + BOOL IsVisible() const + { + return IsWindowVisible(); + } + +#if (_WIN32_IE >= 0x0400) + UINT GetHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBands_Height(m_hWnd); + } +#endif // (_WIN32_IE >= 0x0400) + + HWND GetCommandBar(UINT uBand) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_GetCommandBar(m_hWnd, uBand); + } + + BOOL GetRestoreInformation(UINT uBand, LPCOMMANDBANDSRESTOREINFO pcbr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_GetRestoreInformation(m_hWnd, uBand, pcbr); + } + +// Operations + HWND Create(HWND hWndParent, UINT wID, DWORD dwStyles, HIMAGELIST hImageList = NULL) + { + m_hWnd = ::CommandBands_Create(ModuleHelper::GetModuleInstance(), hWndParent, wID, dwStyles, hImageList); + ATLASSERT(::IsWindow(m_hWnd)); + return m_hWnd; + } + + BOOL AddAdornments(DWORD dwFlags = 0, LPREBARBANDINFO prbbi = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_AddAdornments(m_hWnd, ModuleHelper::GetModuleInstance(), dwFlags, prbbi); + } + + BOOL AddBands(UINT uBandCount, LPREBARBANDINFO prbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_AddBands(m_hWnd, ModuleHelper::GetModuleInstance(), uBandCount, prbbi); + } + + BOOL Show(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_Show(m_hWnd, bShow); + } +}; + +typedef CCECommandBandsCtrlT CCECommandBandsCtrl; + +#endif // _WIN32_WCE + +}; // namespace WTL + +#endif // __ATLCTRLS_H__ diff --git a/ext/CrashServer/external/WTL/Include/atlctrlx.h b/ext/CrashServer/external/WTL/Include/atlctrlx.h new file mode 100644 index 000000000..64982d1db --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atlctrlx.h @@ -0,0 +1,4827 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLCTRLX_H__ +#define __ATLCTRLX_H__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLAPP_H__ + #error atlctrlx.h requires atlapp.h to be included first +#endif + +#ifndef __ATLCTRLS_H__ + #error atlctrlx.h requires atlctrls.h to be included first +#endif + +#ifndef WM_UPDATEUISTATE + #define WM_UPDATEUISTATE 0x0128 +#endif // !WM_UPDATEUISTATE + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CBitmapButtonImpl +// CBitmapButton +// CCheckListViewCtrlImpl +// CCheckListViewCtrl +// CHyperLinkImpl +// CHyperLink +// CWaitCursor +// CCustomWaitCursor +// CMultiPaneStatusBarCtrlImpl +// CMultiPaneStatusBarCtrl +// CPaneContainerImpl +// CPaneContainer +// CSortListViewImpl +// CSortListViewCtrlImpl +// CSortListViewCtrl +// CTabViewImpl +// CTabView + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CBitmapButton - bitmap button implementation + +#ifndef _WIN32_WCE + +// bitmap button extended styles +#define BMPBTN_HOVER 0x00000001 +#define BMPBTN_AUTO3D_SINGLE 0x00000002 +#define BMPBTN_AUTO3D_DOUBLE 0x00000004 +#define BMPBTN_AUTOSIZE 0x00000008 +#define BMPBTN_SHAREIMAGELISTS 0x00000010 +#define BMPBTN_AUTOFIRE 0x00000020 + +template +class ATL_NO_VTABLE CBitmapButtonImpl : public ATL::CWindowImpl< T, TBase, TWinTraits> +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + + enum + { + _nImageNormal = 0, + _nImagePushed, + _nImageFocusOrHover, + _nImageDisabled, + + _nImageCount = 4, + }; + + enum + { + ID_TIMER_FIRST = 1000, + ID_TIMER_REPEAT = 1001 + }; + + // Bitmap button specific extended styles + DWORD m_dwExtendedStyle; + + CImageList m_ImageList; + int m_nImage[_nImageCount]; + + CToolTipCtrl m_tip; + LPTSTR m_lpstrToolTipText; + + // Internal states + unsigned m_fMouseOver:1; + unsigned m_fFocus:1; + unsigned m_fPressed:1; + + +// Constructor/Destructor + CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) : + m_ImageList(hImageList), m_dwExtendedStyle(dwExtendedStyle), + m_lpstrToolTipText(NULL), + m_fMouseOver(0), m_fFocus(0), m_fPressed(0) + { + m_nImage[_nImageNormal] = -1; + m_nImage[_nImagePushed] = -1; + m_nImage[_nImageFocusOrHover] = -1; + m_nImage[_nImageDisabled] = -1; + } + + ~CBitmapButtonImpl() + { + if((m_dwExtendedStyle & BMPBTN_SHAREIMAGELISTS) == 0) + m_ImageList.Destroy(); + delete [] m_lpstrToolTipText; + } + + // overridden to provide proper initialization + BOOL SubclassWindow(HWND hWnd) + { +#if (_MSC_VER >= 1300) + BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass; + BOOL bRet = _baseClass::SubclassWindow(hWnd); +#endif // !(_MSC_VER >= 1300) + if(bRet) + Init(); + return bRet; + } + +// Attributes + DWORD GetBitmapButtonExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + + HIMAGELIST GetImageList() const + { + return m_ImageList; + } + + HIMAGELIST SetImageList(HIMAGELIST hImageList) + { + HIMAGELIST hImageListPrev = m_ImageList; + m_ImageList = hImageList; + if((m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0 && ::IsWindow(m_hWnd)) + SizeToImage(); + return hImageListPrev; + } + + int GetToolTipTextLength() const + { + return (m_lpstrToolTipText == NULL) ? -1 : lstrlen(m_lpstrToolTipText); + } + + bool GetToolTipText(LPTSTR lpstrText, int nLength) const + { + ATLASSERT(lpstrText != NULL); + if(m_lpstrToolTipText == NULL) + return false; + + errno_t nRet = SecureHelper::strncpy_x(lpstrText, nLength, m_lpstrToolTipText, _TRUNCATE); + + return (nRet == 0 || nRet == STRUNCATE); + } + + bool SetToolTipText(LPCTSTR lpstrText) + { + if(m_lpstrToolTipText != NULL) + { + delete [] m_lpstrToolTipText; + m_lpstrToolTipText = NULL; + } + + if(lpstrText == NULL) + { + if(m_tip.IsWindow()) + m_tip.Activate(FALSE); + return true; + } + + int cchLen = lstrlen(lpstrText) + 1; + ATLTRY(m_lpstrToolTipText = new TCHAR[cchLen]); + if(m_lpstrToolTipText == NULL) + return false; + + SecureHelper::strcpy_x(m_lpstrToolTipText, cchLen, lpstrText); + if(m_tip.IsWindow()) + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrToolTipText); + } + + return true; + } + +// Operations + void SetImages(int nNormal, int nPushed = -1, int nFocusOrHover = -1, int nDisabled = -1) + { + if(nNormal != -1) + m_nImage[_nImageNormal] = nNormal; + if(nPushed != -1) + m_nImage[_nImagePushed] = nPushed; + if(nFocusOrHover != -1) + m_nImage[_nImageFocusOrHover] = nFocusOrHover; + if(nDisabled != -1) + m_nImage[_nImageDisabled] = nDisabled; + } + + BOOL SizeToImage() + { + ATLASSERT(::IsWindow(m_hWnd) && m_ImageList.m_hImageList != NULL); + int cx = 0; + int cy = 0; + if(!m_ImageList.GetIconSize(cx, cy)) + return FALSE; + return ResizeClient(cx, cy); + } + +// Overrideables + void DoPaint(CDCHandle dc) + { + ATLASSERT(m_ImageList.m_hImageList != NULL); // image list must be set + ATLASSERT(m_nImage[0] != -1); // main bitmap must be set + + // set bitmap according to the current button state + int nImage = -1; + bool bHover = IsHoverMode(); + if(!IsWindowEnabled()) + nImage = m_nImage[_nImageDisabled]; + else if(m_fPressed == 1) + nImage = m_nImage[_nImagePushed]; + else if((!bHover && m_fFocus == 1) || (bHover && m_fMouseOver == 1)) + nImage = m_nImage[_nImageFocusOrHover]; + if(nImage == -1) // not there, use default one + nImage = m_nImage[_nImageNormal]; + + // draw the button image + int xyPos = 0; + if((m_fPressed == 1) && ((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) && (m_nImage[_nImagePushed] == -1)) + xyPos = 1; + m_ImageList.Draw(dc, nImage, xyPos, xyPos, ILD_NORMAL); + + // draw 3D border if required + if((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) + { + RECT rect; + GetClientRect(&rect); + + if(m_fPressed == 1) + dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_SUNKENOUTER : EDGE_SUNKEN, BF_RECT); + else if(!bHover || m_fMouseOver == 1) + dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_RAISEDINNER : EDGE_RAISED, BF_RECT); + + if(!bHover && m_fFocus == 1) + { + ::InflateRect(&rect, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE)); + dc.DrawFocusRect(&rect); + } + } + } + +// Message map and handlers + BEGIN_MSG_MAP(CBitmapButtonImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + MESSAGE_HANDLER(WM_SETFOCUS, OnFocus) + MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) + MESSAGE_HANDLER(WM_ENABLE, OnEnable) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) + MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) + MESSAGE_HANDLER(WM_KEYUP, OnKeyUp) + MESSAGE_HANDLER(WM_TIMER, OnTimer) + MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + Init(); + bHandled = FALSE; + return 1; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_tip.IsWindow()) + { + m_tip.DestroyWindow(); + m_tip.m_hWnd = NULL; + } + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + MSG msg = { m_hWnd, uMsg, wParam, lParam }; + if(m_tip.IsWindow()) + m_tip.RelayEvent(&msg); + bHandled = FALSE; + return 1; + } + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + if(wParam != NULL) + { + pT->DoPaint((HDC)wParam); + } + else + { + CPaintDC dc(m_hWnd); + pT->DoPaint(dc.m_hDC); + } + return 0; + } + + LRESULT OnFocus(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + m_fFocus = (uMsg == WM_SETFOCUS) ? 1 : 0; + Invalidate(); + UpdateWindow(); + bHandled = FALSE; + return 1; + } + + LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = 0; + if(IsHoverMode()) + SetCapture(); + else + lRet = DefWindowProc(uMsg, wParam, lParam); + if(::GetCapture() == m_hWnd) + { + m_fPressed = 1; + Invalidate(); + UpdateWindow(); + } + if((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0) + { + int nElapse = 250; + int nDelay = 0; + if(::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &nDelay, 0)) + nElapse += nDelay * 250; // all milli-seconds + SetTimer(ID_TIMER_FIRST, nElapse); + } + return lRet; + } + + LRESULT OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = 0; + if(!IsHoverMode()) + lRet = DefWindowProc(uMsg, wParam, lParam); + if(::GetCapture() != m_hWnd) + SetCapture(); + if(m_fPressed == 0) + { + m_fPressed = 1; + Invalidate(); + UpdateWindow(); + } + return lRet; + } + + LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = 0; + bool bHover = IsHoverMode(); + if(!bHover) + lRet = DefWindowProc(uMsg, wParam, lParam); + if(::GetCapture() == m_hWnd) + { + if(bHover && m_fPressed == 1) + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + ::ReleaseCapture(); + } + return lRet; + } + + LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_fPressed == 1) + { + m_fPressed = 0; + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + Invalidate(); + UpdateWindow(); + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(::GetCapture() == m_hWnd) + { + POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + ClientToScreen(&ptCursor); + RECT rect = { 0 }; + GetWindowRect(&rect); + unsigned int uPressed = ::PtInRect(&rect, ptCursor) ? 1 : 0; + if(m_fPressed != uPressed) + { + m_fPressed = uPressed; + Invalidate(); + UpdateWindow(); + } + } + else if(IsHoverMode() && m_fMouseOver == 0) + { + m_fMouseOver = 1; + Invalidate(); + UpdateWindow(); + StartTrackMouseLeave(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_fMouseOver == 1) + { + m_fMouseOver = 0; + Invalidate(); + UpdateWindow(); + } + return 0; + } + + LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam == VK_SPACE && IsHoverMode()) + return 0; // ignore if in hover mode + if(wParam == VK_SPACE && m_fPressed == 0) + { + m_fPressed = 1; + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam == VK_SPACE && IsHoverMode()) + return 0; // ignore if in hover mode + if(wParam == VK_SPACE && m_fPressed == 1) + { + m_fPressed = 0; + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + ATLASSERT((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0); + switch(wParam) // timer ID + { + case ID_TIMER_FIRST: + KillTimer(ID_TIMER_FIRST); + if(m_fPressed == 1) + { + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + int nElapse = 250; + int nRepeat = 40; + if(::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &nRepeat, 0)) + nElapse = 10000 / (10 * nRepeat + 25); // milli-seconds, approximated + SetTimer(ID_TIMER_REPEAT, nElapse); + } + break; + case ID_TIMER_REPEAT: + if(m_fPressed == 1) + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + else if(::GetCapture() != m_hWnd) + KillTimer(ID_TIMER_REPEAT); + break; + default: // not our timer + break; + } + return 0; + } + + LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + // If the control is subclassed or superclassed, this message can cause + // repainting without WM_PAINT. We don't use this state, so just do nothing. + return 0; + } + +// Implementation + void Init() + { + // We need this style to prevent Windows from painting the button + ModifyStyle(0, BS_OWNERDRAW); + + // create a tool tip + m_tip.Create(m_hWnd); + ATLASSERT(m_tip.IsWindow()); + if(m_tip.IsWindow() && m_lpstrToolTipText != NULL) + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrToolTipText); + } + + if(m_ImageList.m_hImageList != NULL && (m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0) + SizeToImage(); + } + + BOOL StartTrackMouseLeave() + { + TRACKMOUSEEVENT tme = { 0 }; + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = m_hWnd; + return _TrackMouseEvent(&tme); + } + + bool IsHoverMode() const + { + return ((m_dwExtendedStyle & BMPBTN_HOVER) != 0); + } +}; + + +class CBitmapButton : public CBitmapButtonImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName()) + + CBitmapButton(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) : + CBitmapButtonImpl(dwExtendedStyle, hImageList) + { } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CCheckListCtrlView - list view control with check boxes + +template +class CCheckListViewCtrlImplTraits +{ +public: + static DWORD GetWndStyle(DWORD dwStyle) + { + return (dwStyle == 0) ? t_dwStyle : dwStyle; + } + + static DWORD GetWndExStyle(DWORD dwExStyle) + { + return (dwExStyle == 0) ? t_dwExStyle : dwExStyle; + } + + static DWORD GetExtendedLVStyle() + { + return t_dwExListViewStyle; + } +}; + +typedef CCheckListViewCtrlImplTraits CCheckListViewCtrlTraits; + +template +class ATL_NO_VTABLE CCheckListViewCtrlImpl : public ATL::CWindowImpl +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + +// Attributes + static DWORD GetExtendedLVStyle() + { + return TWinTraits::GetExtendedLVStyle(); + } + +// Operations + BOOL SubclassWindow(HWND hWnd) + { +#if (_MSC_VER >= 1300) + BOOL bRet = ATL::CWindowImplBaseT< TBase, TWinTraits>::SubclassWindow(hWnd); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImplBaseT< TBase, TWinTraits> _baseClass; + BOOL bRet = _baseClass::SubclassWindow(hWnd); +#endif // !(_MSC_VER >= 1300) + if(bRet) + { + T* pT = static_cast(this); + pT; + ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); + SetExtendedListViewStyle(pT->GetExtendedLVStyle()); + } + return bRet; + } + + void CheckSelectedItems(int nCurrItem) + { + // first check if this item is selected + LVITEM lvi = { 0 }; + lvi.iItem = nCurrItem; + lvi.iSubItem = 0; + lvi.mask = LVIF_STATE; + lvi.stateMask = LVIS_SELECTED; + GetItem(&lvi); + // if item is not selected, don't do anything + if(!(lvi.state & LVIS_SELECTED)) + return; + // new check state will be reverse of the current state, + BOOL bCheck = !GetCheckState(nCurrItem); + int nItem = -1; + int nOldItem = -1; + while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1) + { + if(nItem != nCurrItem) + SetCheckState(nItem, bCheck); + nOldItem = nItem; + } + } + +// Implementation + BEGIN_MSG_MAP(CCheckListViewCtrlImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) + END_MSG_MAP() + + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + // first let list view control initialize everything + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + T* pT = static_cast(this); + pT; + ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); + SetExtendedListViewStyle(pT->GetExtendedLVStyle()); + return lRet; + } + + LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + LVHITTESTINFO lvh = { 0 }; + lvh.pt = ptMsg; + if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0) + { + T* pT = static_cast(this); + pT->CheckSelectedItems(lvh.iItem); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam == VK_SPACE) + { + int nCurrItem = GetNextItem(-1, LVNI_FOCUSED); + if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0) + { + T* pT = static_cast(this); + pT->CheckSelectedItems(nCurrItem); + } + } + bHandled = FALSE; + return 1; + } +}; + +class CCheckListViewCtrl : public CCheckListViewCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_CheckListView"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CHyperLink - hyper link control implementation + +#if (WINVER < 0x0500) && !defined(_WIN32_WCE) +__declspec(selectany) struct +{ + enum { cxWidth = 32, cyHeight = 32 }; + int xHotSpot; + int yHotSpot; + unsigned char arrANDPlane[cxWidth * cyHeight / 8]; + unsigned char arrXORPlane[cxWidth * cyHeight / 8]; +} _AtlHyperLink_CursorData = +{ + 5, 0, + { + 0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, + 0xF0, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, + 0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }, + { + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xD8, 0x00, 0x00, + 0x06, 0xDA, 0x00, 0x00, 0x06, 0xDB, 0x00, 0x00, 0x67, 0xFB, 0x00, 0x00, 0x77, 0xFF, 0x00, 0x00, + 0x37, 0xFF, 0x00, 0x00, 0x17, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, + 0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; +#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) + +#define HLINK_UNDERLINED 0x00000000 +#define HLINK_NOTUNDERLINED 0x00000001 +#define HLINK_UNDERLINEHOVER 0x00000002 +#define HLINK_COMMANDBUTTON 0x00000004 +#define HLINK_NOTIFYBUTTON 0x0000000C +#define HLINK_USETAGS 0x00000010 +#define HLINK_USETAGSBOLD 0x00000030 +#define HLINK_NOTOOLTIP 0x00000040 + +// Notes: +// - HLINK_USETAGS and HLINK_USETAGSBOLD are always left-aligned +// - When HLINK_USETAGSBOLD is used, the underlined styles will be ignored + +template +class ATL_NO_VTABLE CHyperLinkImpl : public ATL::CWindowImpl< T, TBase, TWinTraits > +{ +public: + LPTSTR m_lpstrLabel; + LPTSTR m_lpstrHyperLink; + + HCURSOR m_hCursor; + HFONT m_hFont; + HFONT m_hFontNormal; + + RECT m_rcLink; +#ifndef _WIN32_WCE + CToolTipCtrl m_tip; +#endif // !_WIN32_WCE + + COLORREF m_clrLink; + COLORREF m_clrVisited; + + DWORD m_dwExtendedStyle; // Hyper Link specific extended styles + + bool m_bPaintLabel:1; + bool m_bVisited:1; + bool m_bHover:1; + bool m_bInternalLinkFont:1; + + +// Constructor/Destructor + CHyperLinkImpl(DWORD dwExtendedStyle = HLINK_UNDERLINED) : + m_lpstrLabel(NULL), m_lpstrHyperLink(NULL), + m_hCursor(NULL), m_hFont(NULL), m_hFontNormal(NULL), + m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128)), + m_dwExtendedStyle(dwExtendedStyle), + m_bPaintLabel(true), m_bVisited(false), + m_bHover(false), m_bInternalLinkFont(false) + { + ::SetRectEmpty(&m_rcLink); + } + + ~CHyperLinkImpl() + { + delete [] m_lpstrLabel; + delete [] m_lpstrHyperLink; + if(m_bInternalLinkFont && m_hFont != NULL) + ::DeleteObject(m_hFont); +#if (WINVER < 0x0500) && !defined(_WIN32_WCE) + // It was created, not loaded, so we have to destroy it + if(m_hCursor != NULL) + ::DestroyCursor(m_hCursor); +#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) + } + +// Attributes + DWORD GetHyperLinkExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetHyperLinkExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + + bool GetLabel(LPTSTR lpstrBuffer, int nLength) const + { + if(m_lpstrLabel == NULL) + return false; + ATLASSERT(lpstrBuffer != NULL); + if(nLength <= lstrlen(m_lpstrLabel)) + return false; + + SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrLabel); + + return true; + } + + bool SetLabel(LPCTSTR lpstrLabel) + { + delete [] m_lpstrLabel; + m_lpstrLabel = NULL; + int cchLen = lstrlen(lpstrLabel) + 1; + ATLTRY(m_lpstrLabel = new TCHAR[cchLen]); + if(m_lpstrLabel == NULL) + return false; + + SecureHelper::strcpy_x(m_lpstrLabel, cchLen, lpstrLabel); + T* pT = static_cast(this); + pT->CalcLabelRect(); + + if(m_hWnd != NULL) + SetWindowText(lpstrLabel); // Set this for accessibility + + return true; + } + + bool GetHyperLink(LPTSTR lpstrBuffer, int nLength) const + { + if(m_lpstrHyperLink == NULL) + return false; + ATLASSERT(lpstrBuffer != NULL); + if(nLength <= lstrlen(m_lpstrHyperLink)) + return false; + + SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrHyperLink); + + return true; + } + + bool SetHyperLink(LPCTSTR lpstrLink) + { + delete [] m_lpstrHyperLink; + m_lpstrHyperLink = NULL; + int cchLen = lstrlen(lpstrLink) + 1; + ATLTRY(m_lpstrHyperLink = new TCHAR[cchLen]); + if(m_lpstrHyperLink == NULL) + return false; + + SecureHelper::strcpy_x(m_lpstrHyperLink, cchLen, lpstrLink); + if(m_lpstrLabel == NULL) + { + T* pT = static_cast(this); + pT->CalcLabelRect(); + } +#ifndef _WIN32_WCE + if(m_tip.IsWindow()) + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1); + } +#endif // !_WIN32_WCE + return true; + } + + HFONT GetLinkFont() const + { + return m_hFont; + } + + void SetLinkFont(HFONT hFont) + { + if(m_bInternalLinkFont && m_hFont != NULL) + { + ::DeleteObject(m_hFont); + m_bInternalLinkFont = false; + } + m_hFont = hFont; + } + + int GetIdealHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) + return -1; + if(!m_bPaintLabel) + return -1; + + CClientDC dc(m_hWnd); + RECT rect = { 0 }; + GetClientRect(&rect); + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + RECT rcText = rect; + dc.DrawText(_T("NS"), -1, &rcText, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + dc.SelectFont(m_hFont); + RECT rcLink = rect; + dc.DrawText(_T("NS"), -1, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + dc.SelectFont(hFontOld); + return max(rcText.bottom - rcText.top, rcLink.bottom - rcLink.top); + } + + bool GetIdealSize(SIZE& size) const + { + int cx = 0, cy = 0; + bool bRet = GetIdealSize(cx, cy); + if(bRet) + { + size.cx = cx; + size.cy = cy; + } + return bRet; + } + + bool GetIdealSize(int& cx, int& cy) const + { + ATLASSERT(::IsWindow(m_hWnd)); + if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) + return false; + if(!m_bPaintLabel) + return false; + + CClientDC dc(m_hWnd); + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + RECT rcAll = rcClient; + + if(IsUsingTags()) + { + // find tags and label parts + LPTSTR lpstrLeft = NULL; + int cchLeft = 0; + LPTSTR lpstrLink = NULL; + int cchLink = 0; + LPTSTR lpstrRight = NULL; + int cchRight = 0; + + const T* pT = static_cast(this); + pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); + + // get label part rects + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + RECT rcLeft = rcClient; + dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + + dc.SelectFont(m_hFont); + RECT rcLink = { rcLeft.right, rcLeft.top, rcClient.right, rcClient.bottom }; + dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + + dc.SelectFont(m_hFontNormal); + RECT rcRight = { rcLink.right, rcLink.top, rcClient.right, rcClient.bottom }; + dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + + dc.SelectFont(hFontOld); + + int cyMax = max(rcLeft.bottom, max(rcLink.bottom, rcRight.bottom)); + ::SetRect(&rcAll, rcLeft.left, rcLeft.top, rcRight.right, cyMax); + } + else + { + HFONT hOldFont = NULL; + if(m_hFont != NULL) + hOldFont = dc.SelectFont(m_hFont); + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + DWORD dwStyle = GetStyle(); + int nDrawStyle = DT_LEFT; + if (dwStyle & SS_CENTER) + nDrawStyle = DT_CENTER; + else if (dwStyle & SS_RIGHT) + nDrawStyle = DT_RIGHT; + dc.DrawText(lpstrText, -1, &rcAll, nDrawStyle | DT_WORDBREAK | DT_CALCRECT); + if(m_hFont != NULL) + dc.SelectFont(hOldFont); + if (dwStyle & SS_CENTER) + { + int dx = (rcClient.right - rcAll.right) / 2; + ::OffsetRect(&rcAll, dx, 0); + } + else if (dwStyle & SS_RIGHT) + { + int dx = rcClient.right - rcAll.right; + ::OffsetRect(&rcAll, dx, 0); + } + } + + cx = rcAll.right - rcAll.left; + cy = rcAll.bottom - rcAll.top; + + return true; + } + + // for command buttons only + bool GetToolTipText(LPTSTR lpstrBuffer, int nLength) const + { + ATLASSERT(IsCommandButton()); + return GetHyperLink(lpstrBuffer, nLength); + } + + bool SetToolTipText(LPCTSTR lpstrToolTipText) + { + ATLASSERT(IsCommandButton()); + return SetHyperLink(lpstrToolTipText); + } + +// Operations + BOOL SubclassWindow(HWND hWnd) + { + ATLASSERT(m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); +#if (_MSC_VER >= 1300) + BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass; + BOOL bRet = _baseClass::SubclassWindow(hWnd); +#endif // !(_MSC_VER >= 1300) + if(bRet) + { + T* pT = static_cast(this); + pT->Init(); + } + return bRet; + } + + bool Navigate() + { + ATLASSERT(::IsWindow(m_hWnd)); + bool bRet = true; + if(IsNotifyButton()) + { + NMHDR nmhdr = { m_hWnd, GetDlgCtrlID(), NM_CLICK }; + ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr); + } + else if(IsCommandButton()) + { + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + } + else + { + ATLASSERT(m_lpstrHyperLink != NULL); +#ifndef _WIN32_WCE + DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL); + bRet = (dwRet > 32); +#else // CE specific + SHELLEXECUTEINFO shExeInfo = { sizeof(SHELLEXECUTEINFO), 0, 0, L"open", m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0, 0 }; + ::ShellExecuteEx(&shExeInfo); + DWORD_PTR dwRet = (DWORD_PTR)shExeInfo.hInstApp; + bRet = (dwRet == 0) || (dwRet > 32); +#endif // _WIN32_WCE + ATLASSERT(bRet); + if(bRet) + { + m_bVisited = true; + Invalidate(); + } + } + return bRet; + } + +// Message map and handlers + BEGIN_MSG_MAP(CHyperLinkImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_SETFOCUS, OnFocus) + MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_CHAR, OnChar) + MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode) + MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) + MESSAGE_HANDLER(WM_ENABLE, OnEnable) + MESSAGE_HANDLER(WM_GETFONT, OnGetFont) + MESSAGE_HANDLER(WM_SETFONT, OnSetFont) + MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState) + MESSAGE_HANDLER(WM_SIZE, OnSize) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Init(); + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_tip.IsWindow()) + { + m_tip.DestroyWindow(); + m_tip.m_hWnd = NULL; + } + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + MSG msg = { m_hWnd, uMsg, wParam, lParam }; + if(m_tip.IsWindow() && IsUsingToolTip()) + m_tip.RelayEvent(&msg); + bHandled = FALSE; + return 1; + } +#endif // !_WIN32_WCE + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background painting needed (we do it all during WM_PAINT) + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(!m_bPaintLabel) + { + bHandled = FALSE; + return 1; + } + + T* pT = static_cast(this); + if(wParam != NULL) + { + pT->DoEraseBackground((HDC)wParam); + pT->DoPaint((HDC)wParam); + } + else + { + CPaintDC dc(m_hWnd); + pT->DoEraseBackground(dc.m_hDC); + pT->DoPaint(dc.m_hDC); + } + + return 0; + } + + LRESULT OnFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bPaintLabel) + Invalidate(); + else + bHandled = FALSE; + return 0; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt)) + { + ::SetCursor(m_hCursor); + if(IsUnderlineHover()) + { + if(!m_bHover) + { + m_bHover = true; + InvalidateRect(&m_rcLink); + UpdateWindow(); +#ifndef _WIN32_WCE + StartTrackMouseLeave(); +#endif // !_WIN32_WCE + } + } + } + else + { + if(IsUnderlineHover()) + { + if(m_bHover) + { + m_bHover = false; + InvalidateRect(&m_rcLink); + UpdateWindow(); + } + } + bHandled = FALSE; + } + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(IsUnderlineHover() && m_bHover) + { + m_bHover = false; + InvalidateRect(&m_rcLink); + UpdateWindow(); + } + return 0; + } +#endif // !_WIN32_WCE + + LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if(::PtInRect(&m_rcLink, pt)) + { + SetFocus(); + SetCapture(); + } + return 0; + } + + LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + if(GetCapture() == m_hWnd) + { + ReleaseCapture(); + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if(::PtInRect(&m_rcLink, pt)) + { + T* pT = static_cast(this); + pT->Navigate(); + } + } + return 0; + } + + LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(wParam == VK_RETURN || wParam == VK_SPACE) + { + T* pT = static_cast(this); + pT->Navigate(); + } + return 0; + } + + LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return DLGC_WANTCHARS; + } + + LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + POINT pt = { 0, 0 }; + GetCursorPos(&pt); + ScreenToClient(&pt); + if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt)) + { + return TRUE; + } + bHandled = FALSE; + return FALSE; + } + + LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + Invalidate(); + UpdateWindow(); + return 0; + } + + LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)m_hFontNormal; + } + + LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + m_hFontNormal = (HFONT)wParam; + if((BOOL)lParam) + { + Invalidate(); + UpdateWindow(); + } + return 0; + } + + LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + // If the control is subclassed or superclassed, this message can cause + // repainting without WM_PAINT. We don't use this state, so just do nothing. + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->CalcLabelRect(); + pT->Invalidate(); + return 0; + } + +// Implementation + void Init() + { + ATLASSERT(::IsWindow(m_hWnd)); + + // Check if we should paint a label + const int cchBuff = 8; + TCHAR szBuffer[cchBuff] = { 0 }; + if(::GetClassName(m_hWnd, szBuffer, cchBuff)) + { + if(lstrcmpi(szBuffer, _T("static")) == 0) + { + ModifyStyle(0, SS_NOTIFY); // we need this + DWORD dwStyle = GetStyle() & 0x000000FF; +#ifndef _WIN32_WCE + if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT || + dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME || + dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW || + dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE) +#else // CE specific + if(dwStyle == SS_ICON || dwStyle == SS_BITMAP) +#endif // _WIN32_WCE + m_bPaintLabel = false; + } + } + + // create or load a cursor +#if (WINVER >= 0x0500) || defined(_WIN32_WCE) + m_hCursor = ::LoadCursor(NULL, IDC_HAND); +#else + m_hCursor = ::CreateCursor(ModuleHelper::GetModuleInstance(), _AtlHyperLink_CursorData.xHotSpot, _AtlHyperLink_CursorData.yHotSpot, _AtlHyperLink_CursorData.cxWidth, _AtlHyperLink_CursorData.cyHeight, _AtlHyperLink_CursorData.arrANDPlane, _AtlHyperLink_CursorData.arrXORPlane); +#endif + ATLASSERT(m_hCursor != NULL); + + // set font + if(m_bPaintLabel) + { + ATL::CWindow wnd = GetParent(); + m_hFontNormal = wnd.GetFont(); + if(m_hFontNormal == NULL) + m_hFontNormal = (HFONT)::GetStockObject(SYSTEM_FONT); + if(m_hFontNormal != NULL && m_hFont == NULL) + { + LOGFONT lf = { 0 }; + CFontHandle font = m_hFontNormal; + font.GetLogFont(&lf); + if(IsUsingTagsBold()) + lf.lfWeight = FW_BOLD; + else if(!IsNotUnderlined()) + lf.lfUnderline = TRUE; + m_hFont = ::CreateFontIndirect(&lf); + m_bInternalLinkFont = true; + ATLASSERT(m_hFont != NULL); + } + } + +#ifndef _WIN32_WCE + // create a tool tip + m_tip.Create(m_hWnd); + ATLASSERT(m_tip.IsWindow()); +#endif // !_WIN32_WCE + + // set label (defaults to window text) + if(m_lpstrLabel == NULL) + { + int nLen = GetWindowTextLength(); + if(nLen > 0) + { + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLen + 1); + ATLASSERT(lpstrText != NULL); + if((lpstrText != NULL) && (GetWindowText(lpstrText, nLen + 1) > 0)) + SetLabel(lpstrText); + } + } + + T* pT = static_cast(this); + pT->CalcLabelRect(); + + // set hyperlink (defaults to label), or just activate tool tip if already set + if(m_lpstrHyperLink == NULL && !IsCommandButton()) + { + if(m_lpstrLabel != NULL) + SetHyperLink(m_lpstrLabel); + } +#ifndef _WIN32_WCE + else + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1); + } +#endif // !_WIN32_WCE + + // set link colors + if(m_bPaintLabel) + { + ATL::CRegKey rk; + LONG lRet = rk.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\Settings")); + if(lRet == 0) + { + const int cchValue = 12; + TCHAR szValue[cchValue] = { 0 }; +#if (_ATL_VER >= 0x0700) + ULONG ulCount = cchValue; + lRet = rk.QueryStringValue(_T("Anchor Color"), szValue, &ulCount); +#else + DWORD dwCount = cchValue * sizeof(TCHAR); + lRet = rk.QueryValue(szValue, _T("Anchor Color"), &dwCount); +#endif + if(lRet == 0) + { + COLORREF clr = pT->_ParseColorString(szValue); + ATLASSERT(clr != CLR_INVALID); + if(clr != CLR_INVALID) + m_clrLink = clr; + } + +#if (_ATL_VER >= 0x0700) + ulCount = cchValue; + lRet = rk.QueryStringValue(_T("Anchor Color Visited"), szValue, &ulCount); +#else + dwCount = cchValue * sizeof(TCHAR); + lRet = rk.QueryValue(szValue, _T("Anchor Color Visited"), &dwCount); +#endif + if(lRet == 0) + { + COLORREF clr = pT->_ParseColorString(szValue); + ATLASSERT(clr != CLR_INVALID); + if(clr != CLR_INVALID) + m_clrVisited = clr; + } + } + } + } + + static COLORREF _ParseColorString(LPTSTR lpstr) + { + int c[3] = { -1, -1, -1 }; + LPTSTR p = NULL; + for(int i = 0; i < 2; i++) + { + for(p = lpstr; *p != _T('\0'); p = ::CharNext(p)) + { + if(*p == _T(',')) + { + *p = _T('\0'); + c[i] = T::_xttoi(lpstr); + lpstr = &p[1]; + break; + } + } + if(c[i] == -1) + return CLR_INVALID; + } + if(*lpstr == _T('\0')) + return CLR_INVALID; + c[2] = T::_xttoi(lpstr); + + return RGB(c[0], c[1], c[2]); + } + + bool CalcLabelRect() + { + if(!::IsWindow(m_hWnd)) + return false; + if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) + return false; + + CClientDC dc(m_hWnd); + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + m_rcLink = rcClient; + if(!m_bPaintLabel) + return true; + + if(IsUsingTags()) + { + // find tags and label parts + LPTSTR lpstrLeft = NULL; + int cchLeft = 0; + LPTSTR lpstrLink = NULL; + int cchLink = 0; + LPTSTR lpstrRight = NULL; + int cchRight = 0; + + T* pT = static_cast(this); + pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); + ATLASSERT(lpstrLink != NULL); + ATLASSERT(cchLink > 0); + + // get label part rects + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + + RECT rcLeft = rcClient; + if(lpstrLeft != NULL) + dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + + dc.SelectFont(m_hFont); + RECT rcLink = rcClient; + if(lpstrLeft != NULL) + rcLink.left = rcLeft.right; + dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT); + + dc.SelectFont(hFontOld); + + m_rcLink = rcLink; + } + else + { + HFONT hOldFont = NULL; + if(m_hFont != NULL) + hOldFont = dc.SelectFont(m_hFont); + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + DWORD dwStyle = GetStyle(); + int nDrawStyle = DT_LEFT; + if (dwStyle & SS_CENTER) + nDrawStyle = DT_CENTER; + else if (dwStyle & SS_RIGHT) + nDrawStyle = DT_RIGHT; + dc.DrawText(lpstrText, -1, &m_rcLink, nDrawStyle | DT_WORDBREAK | DT_CALCRECT); + if(m_hFont != NULL) + dc.SelectFont(hOldFont); + if (dwStyle & SS_CENTER) + { + int dx = (rcClient.right - m_rcLink.right) / 2; + ::OffsetRect(&m_rcLink, dx, 0); + } + else if (dwStyle & SS_RIGHT) + { + int dx = rcClient.right - m_rcLink.right; + ::OffsetRect(&m_rcLink, dx, 0); + } + } + + return true; + } + + void CalcLabelParts(LPTSTR& lpstrLeft, int& cchLeft, LPTSTR& lpstrLink, int& cchLink, LPTSTR& lpstrRight, int& cchRight) const + { + lpstrLeft = NULL; + cchLeft = 0; + lpstrLink = NULL; + cchLink = 0; + lpstrRight = NULL; + cchRight = 0; + + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + int cchText = lstrlen(lpstrText); + bool bOutsideLink = true; + for(int i = 0; i < cchText; i++) + { + if(lpstrText[i] != _T('<')) + continue; + + if(bOutsideLink) + { + if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 3, _T("
"), 3) == CSTR_EQUAL) + { + if(i > 0) + { + lpstrLeft = lpstrText; + cchLeft = i; + } + lpstrLink = &lpstrText[i + 3]; + bOutsideLink = false; + } + } + else + { + if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 4, _T(""), 4) == CSTR_EQUAL) + { + cchLink = i - 3 - cchLeft; + if(lpstrText[i + 4] != 0) + { + lpstrRight = &lpstrText[i + 4]; + cchRight = cchText - (i + 4); + break; + } + } + } + } + + } + + void DoEraseBackground(CDCHandle dc) + { + HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC, (LPARAM)m_hWnd); + if(hBrush != NULL) + { + RECT rect = { 0 }; + GetClientRect(&rect); + dc.FillRect(&rect, hBrush); + } + } + + void DoPaint(CDCHandle dc) + { + if(IsUsingTags()) + { + // find tags and label parts + LPTSTR lpstrLeft = NULL; + int cchLeft = 0; + LPTSTR lpstrLink = NULL; + int cchLink = 0; + LPTSTR lpstrRight = NULL; + int cchRight = 0; + + T* pT = static_cast(this); + pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); + + // get label part rects + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + + dc.SetBkMode(TRANSPARENT); + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + + if(lpstrLeft != NULL) + dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | DT_WORDBREAK); + + COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT))); + if(m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) + dc.SelectFont(m_hFont); + else + dc.SelectFont(m_hFontNormal); + + dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | DT_WORDBREAK); + + dc.SetTextColor(clrOld); + dc.SelectFont(m_hFontNormal); + if(lpstrRight != NULL) + { + RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom }; + dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | DT_WORDBREAK); + } + + if(GetFocus() == m_hWnd) + dc.DrawFocusRect(&m_rcLink); + + dc.SelectFont(hFontOld); + } + else + { + dc.SetBkMode(TRANSPARENT); + COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT))); + + HFONT hFontOld = NULL; + if(m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) + hFontOld = dc.SelectFont(m_hFont); + else + hFontOld = dc.SelectFont(m_hFontNormal); + + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + + DWORD dwStyle = GetStyle(); + int nDrawStyle = DT_LEFT; + if (dwStyle & SS_CENTER) + nDrawStyle = DT_CENTER; + else if (dwStyle & SS_RIGHT) + nDrawStyle = DT_RIGHT; + + dc.DrawText(lpstrText, -1, &m_rcLink, nDrawStyle | DT_WORDBREAK); + + if(GetFocus() == m_hWnd) + dc.DrawFocusRect(&m_rcLink); + + dc.SetTextColor(clrOld); + dc.SelectFont(hFontOld); + } + } + +#ifndef _WIN32_WCE + BOOL StartTrackMouseLeave() + { + TRACKMOUSEEVENT tme = { 0 }; + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = m_hWnd; + return _TrackMouseEvent(&tme); + } +#endif // !_WIN32_WCE + +// Implementation helpers + bool IsUnderlined() const + { + return ((m_dwExtendedStyle & (HLINK_NOTUNDERLINED | HLINK_UNDERLINEHOVER)) == 0); + } + + bool IsNotUnderlined() const + { + return ((m_dwExtendedStyle & HLINK_NOTUNDERLINED) != 0); + } + + bool IsUnderlineHover() const + { + return ((m_dwExtendedStyle & HLINK_UNDERLINEHOVER) != 0); + } + + bool IsCommandButton() const + { + return ((m_dwExtendedStyle & HLINK_COMMANDBUTTON) != 0); + } + + bool IsNotifyButton() const + { + return ((m_dwExtendedStyle & HLINK_NOTIFYBUTTON) == HLINK_NOTIFYBUTTON); + } + + bool IsUsingTags() const + { + return ((m_dwExtendedStyle & HLINK_USETAGS) != 0); + } + + bool IsUsingTagsBold() const + { + return ((m_dwExtendedStyle & HLINK_USETAGSBOLD) == HLINK_USETAGSBOLD); + } + + bool IsUsingToolTip() const + { + return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0); + } + + static int _xttoi(const TCHAR* nptr) + { +#ifndef _ATL_MIN_CRT + return _ttoi(nptr); +#else // _ATL_MIN_CRT + while(*nptr == _T(' ')) // skip spaces + ++nptr; + + int c = (int)(_TUCHAR)*nptr++; + int sign = c; // save sign indication + if (c == _T('-') || c == _T('+')) + c = (int)(_TUCHAR)*nptr++; // skip sign + + int total = 0; + while((TCHAR)c >= _T('0') && (TCHAR)c <= _T('9')) + { + total = 10 * total + ((TCHAR)c - _T('0')); // accumulate digit + c = (int)(_TUCHAR)*nptr++; // get next char + } + + // return result, negated if necessary + return ((TCHAR)sign != _T('-')) ? total : -total; +#endif // _ATL_MIN_CRT + } +}; + + +class CHyperLink : public CHyperLinkImpl +{ +public: + DECLARE_WND_CLASS(_T("WTL_HyperLink")) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWaitCursor - displays a wait cursor + +class CWaitCursor +{ +public: +// Data + HCURSOR m_hWaitCursor; + HCURSOR m_hOldCursor; + bool m_bInUse; + +// Constructor/destructor + CWaitCursor(bool bSet = true, LPCTSTR lpstrCursor = IDC_WAIT, bool bSys = true) : m_hOldCursor(NULL), m_bInUse(false) + { + HINSTANCE hInstance = bSys ? NULL : ModuleHelper::GetResourceInstance(); + m_hWaitCursor = ::LoadCursor(hInstance, lpstrCursor); + ATLASSERT(m_hWaitCursor != NULL); + + if(bSet) + Set(); + } + + ~CWaitCursor() + { + Restore(); + } + +// Methods + bool Set() + { + if(m_bInUse) + return false; + m_hOldCursor = ::SetCursor(m_hWaitCursor); + m_bInUse = true; + return true; + } + + bool Restore() + { + if(!m_bInUse) + return false; + ::SetCursor(m_hOldCursor); + m_bInUse = false; + return true; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CCustomWaitCursor - for custom and animated cursors + +class CCustomWaitCursor : public CWaitCursor +{ +public: +// Constructor/destructor + CCustomWaitCursor(ATL::_U_STRINGorID cursor, bool bSet = true, HINSTANCE hInstance = NULL) : + CWaitCursor(false, IDC_WAIT, true) + { + if(hInstance == NULL) + hInstance = ModuleHelper::GetResourceInstance(); + m_hWaitCursor = (HCURSOR)::LoadImage(hInstance, cursor.m_lpstr, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE); + + if(bSet) + Set(); + } + + ~CCustomWaitCursor() + { + Restore(); +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + ::DestroyCursor(m_hWaitCursor); +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CMultiPaneStatusBarCtrl - Status Bar with multiple panes + +template +class ATL_NO_VTABLE CMultiPaneStatusBarCtrlImpl : public ATL::CWindowImpl< T, TBase > +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + +// Data + enum { m_cxPaneMargin = 3 }; + + int m_nPanes; + int* m_pPane; + +// Constructor/destructor + CMultiPaneStatusBarCtrlImpl() : m_nPanes(0), m_pPane(NULL) + { } + + ~CMultiPaneStatusBarCtrlImpl() + { + delete [] m_pPane; + } + +// Methods + HWND Create(HWND hWndParent, LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) + { +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase > _baseClass; + return _baseClass::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID); +#endif // !(_MSC_VER >= 1300) + } + + HWND Create(HWND hWndParent, UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) + { + const int cchMax = 128; // max text length is 127 for status bars (+1 for null) + TCHAR szText[cchMax]; + szText[0] = 0; + ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax); + return Create(hWndParent, szText, dwStyle, nID); + } + + BOOL SetPanes(int* pPanes, int nPanes, bool bSetText = true) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPanes > 0); + + m_nPanes = nPanes; + delete [] m_pPane; + m_pPane = NULL; + + ATLTRY(m_pPane = new int[nPanes]); + ATLASSERT(m_pPane != NULL); + if(m_pPane == NULL) + return FALSE; + + CTempBuffer buff; + int* pPanesPos = buff.Allocate(nPanes); + ATLASSERT(pPanesPos != NULL); + if(pPanesPos == NULL) + return FALSE; + + SecureHelper::memcpy_x(m_pPane, nPanes * sizeof(int), pPanes, nPanes * sizeof(int)); + + // get status bar DC and set font + CClientDC dc(m_hWnd); + HFONT hOldFont = dc.SelectFont(GetFont()); + + // get status bar borders + int arrBorders[3] = { 0 }; + GetBorders(arrBorders); + + const int cchBuff = 128; + TCHAR szBuff[cchBuff] = { 0 }; + SIZE size = { 0, 0 }; + int cxLeft = arrBorders[0]; + + // calculate right edge of each part + for(int i = 0; i < nPanes; i++) + { + if(pPanes[i] == ID_DEFAULT_PANE) + { + // make very large, will be resized later + pPanesPos[i] = INT_MAX / 2; + } + else + { + ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff); + dc.GetTextExtent(szBuff, lstrlen(szBuff), &size); + T* pT = static_cast(this); + pT; + pPanesPos[i] = cxLeft + size.cx + arrBorders[2] + 2 * pT->m_cxPaneMargin; + } + cxLeft = pPanesPos[i]; + } + + BOOL bRet = SetParts(nPanes, pPanesPos); + + if(bRet && bSetText) + { + for(int i = 0; i < nPanes; i++) + { + if(pPanes[i] != ID_DEFAULT_PANE) + { + ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff); + SetPaneText(m_pPane[i], szBuff); + } + } + } + + dc.SelectFont(hOldFont); + return bRet; + } + + bool GetPaneTextLength(int nPaneID, int* pcchLength = NULL, int* pnType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return false; + + int nLength = GetTextLength(nIndex, pnType); + if(pcchLength != NULL) + *pcchLength = nLength; + + return true; + } + + BOOL GetPaneText(int nPaneID, LPTSTR lpstrText, int* pcchLength = NULL, int* pnType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + int nLength = GetText(nIndex, lpstrText, pnType); + if(pcchLength != NULL) + *pcchLength = nLength; + + return TRUE; + } + + BOOL SetPaneText(int nPaneID, LPCTSTR lpstrText, int nType = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + return SetText(nIndex, lpstrText, nType); + } + + BOOL GetPaneRect(int nPaneID, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + return GetRect(nIndex, lpRect); + } + + BOOL SetPaneWidth(int nPaneID, int cxWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPaneID != ID_DEFAULT_PANE); // Can't resize this one + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + // get pane positions + CTempBuffer buff; + int* pPanesPos = buff.Allocate(m_nPanes); + if(pPanesPos == NULL) + return FALSE; + GetParts(m_nPanes, pPanesPos); + // calculate offset + int cxPaneWidth = pPanesPos[nIndex] - ((nIndex == 0) ? 0 : pPanesPos[nIndex - 1]); + int cxOff = cxWidth - cxPaneWidth; + // find variable width pane + int nDef = m_nPanes; + for(int i = 0; i < m_nPanes; i++) + { + if(m_pPane[i] == ID_DEFAULT_PANE) + { + nDef = i; + break; + } + } + // resize + if(nIndex < nDef) // before default pane + { + for(int i = nIndex; i < nDef; i++) + pPanesPos[i] += cxOff; + + } + else // after default one + { + for(int i = nDef; i < nIndex; i++) + pPanesPos[i] -= cxOff; + } + // set pane postions + return SetParts(m_nPanes, pPanesPos); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetPaneTipText(int nPaneID, LPTSTR lpstrText, int nSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + GetTipText(nIndex, lpstrText, nSize); + return TRUE; + } + + BOOL SetPaneTipText(int nPaneID, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + SetTipText(nIndex, lpstrText); + return TRUE; + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) + BOOL GetPaneIcon(int nPaneID, HICON& hIcon) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + hIcon = GetIcon(nIndex); + return TRUE; + } + + BOOL SetPaneIcon(int nPaneID, HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + return SetIcon(nIndex, hIcon); + } +#endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) + +// Message map and handlers + BEGIN_MSG_MAP(CMultiPaneStatusBarCtrlImpl< T >) + MESSAGE_HANDLER(WM_SIZE, OnSize) + END_MSG_MAP() + + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + if(wParam != SIZE_MINIMIZED && m_nPanes > 0) + { + T* pT = static_cast(this); + pT->UpdatePanesLayout(); + } + return lRet; + } + +// Implementation + BOOL UpdatePanesLayout() + { + // get pane positions + CTempBuffer buff; + int* pPanesPos = buff.Allocate(m_nPanes); + ATLASSERT(pPanesPos != NULL); + if(pPanesPos == NULL) + return FALSE; + int nRet = GetParts(m_nPanes, pPanesPos); + ATLASSERT(nRet == m_nPanes); + if(nRet != m_nPanes) + return FALSE; + // calculate offset + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + int cxOff = rcClient.right - pPanesPos[m_nPanes - 1]; +#ifndef _WIN32_WCE + // Move panes left if size grip box is present + if((GetStyle() & SBARS_SIZEGRIP) != 0) + cxOff -= ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXEDGE); +#endif // !_WIN32_WCE + // find variable width pane + int i; + for(i = 0; i < m_nPanes; i++) + { + if(m_pPane[i] == ID_DEFAULT_PANE) + break; + } + // resize all panes from the variable one to the right + if((i < m_nPanes) && (pPanesPos[i] + cxOff) > ((i == 0) ? 0 : pPanesPos[i - 1])) + { + for(; i < m_nPanes; i++) + pPanesPos[i] += cxOff; + } + // set pane postions + return SetParts(m_nPanes, pPanesPos); + } + + int GetPaneIndexFromID(int nPaneID) const + { + for(int i = 0; i < m_nPanes; i++) + { + if(m_pPane[i] == nPaneID) + return i; + } + + return -1; // not found + } +}; + +class CMultiPaneStatusBarCtrl : public CMultiPaneStatusBarCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_MultiPaneStatusBar"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPaneContainer - provides header with title and close button for panes + +// pane container extended styles +#define PANECNT_NOCLOSEBUTTON 0x00000001 +#define PANECNT_VERTICAL 0x00000002 +#define PANECNT_FLATBORDER 0x00000004 +#define PANECNT_NOBORDER 0x00000008 + +template +class ATL_NO_VTABLE CPaneContainerImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CCustomDraw< T > +{ +public: + DECLARE_WND_CLASS_EX(NULL, 0, -1) + +// Constants + enum + { + m_cxyBorder = 2, + m_cxyTextOffset = 4, + m_cxyBtnOffset = 1, + + m_cchTitle = 80, + + m_cxImageTB = 13, + m_cyImageTB = 11, + m_cxyBtnAddTB = 7, + + m_cxToolBar = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder + m_cxyBtnOffset, + + m_xBtnImageLeft = 6, + m_yBtnImageTop = 5, + m_xBtnImageRight = 12, + m_yBtnImageBottom = 11, + + m_nCloseBtnID = ID_PANE_CLOSE + }; + +// Data members + CToolBarCtrl m_tb; + ATL::CWindow m_wndClient; + int m_cxyHeader; + TCHAR m_szTitle[m_cchTitle]; + DWORD m_dwExtendedStyle; // Pane container specific extended styles + + +// Constructor + CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0) + { + m_szTitle[0] = 0; + } + +// Attributes + DWORD GetPaneContainerExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetPaneContainerExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + if(m_hWnd != NULL) + { + T* pT = static_cast(this); + bool bUpdate = false; + + if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) != 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0)) // add close button + { + pT->CreateCloseButton(); + bUpdate = true; + } + else if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) == 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) != 0)) // remove close button + { + pT->DestroyCloseButton(); + bUpdate = true; + } + + if((dwPrevStyle & PANECNT_VERTICAL) != (m_dwExtendedStyle & PANECNT_VERTICAL)) // change orientation + { + pT->CalcSize(); + bUpdate = true; + } + + if((dwPrevStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER)) != + (m_dwExtendedStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER))) // change border + { + bUpdate = true; + } + + if(bUpdate) + pT->UpdateLayout(); + } + return dwPrevStyle; + } + + HWND GetClient() const + { + return m_wndClient; + } + + HWND SetClient(HWND hWndClient) + { + HWND hWndOldClient = m_wndClient; + m_wndClient = hWndClient; + if(m_hWnd != NULL) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + return hWndOldClient; + } + + BOOL GetTitle(LPTSTR lpstrTitle, int cchLength) const + { + ATLASSERT(lpstrTitle != NULL); + + errno_t nRet = SecureHelper::strncpy_x(lpstrTitle, cchLength, m_szTitle, _TRUNCATE); + + return (nRet == 0 || nRet == STRUNCATE); + } + + BOOL SetTitle(LPCTSTR lpstrTitle) + { + ATLASSERT(lpstrTitle != NULL); + + errno_t nRet = SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE); + bool bRet = (nRet == 0 || nRet == STRUNCATE); + if(bRet && m_hWnd != NULL) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + + return bRet; + } + + int GetTitleLength() const + { + return lstrlen(m_szTitle); + } + +// Methods + HWND Create(HWND hWndParent, LPCTSTR lpstrTitle = NULL, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL) + { + if(lpstrTitle != NULL) + SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE); +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; + return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#endif // !(_MSC_VER >= 1300) + } + + HWND Create(HWND hWndParent, UINT uTitleID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL) + { + if(uTitleID != 0U) + ::LoadString(ModuleHelper::GetResourceInstance(), uTitleID, m_szTitle, m_cchTitle); +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; + return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#endif // !(_MSC_VER >= 1300) + } + + BOOL EnableCloseButton(BOOL bEnable) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT; // avoid level 4 warning + return (m_tb.m_hWnd != NULL) ? m_tb.EnableButton(pT->m_nCloseBtnID, bEnable) : FALSE; + } + + void UpdateLayout() + { + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + T* pT = static_cast(this); + pT->UpdateLayout(rcClient.right, rcClient.bottom); + } + +// Message map and handlers + BEGIN_MSG_MAP(CPaneContainerImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_NOTIFY, OnNotify) + MESSAGE_HANDLER(WM_COMMAND, OnCommand) + FORWARD_NOTIFICATIONS() + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->CalcSize(); + + if((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0) + pT->CreateCloseButton(); + + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + return 0; + } + + LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetFocus(); + return 0; + } + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + if(wParam != NULL) + { + pT->DrawPaneTitle((HDC)wParam); + + if(m_wndClient.m_hWnd == NULL) // no client window + pT->DrawPane((HDC)wParam); + } + else + { + CPaintDC dc(m_hWnd); + pT->DrawPaneTitle(dc.m_hDC); + + if(m_wndClient.m_hWnd == NULL) // no client window + pT->DrawPane(dc.m_hDC); + } + + return 0; + } + + LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_tb.m_hWnd == NULL) + { + bHandled = FALSE; + return 1; + } + + T* pT = static_cast(this); + pT; + LPNMHDR lpnmh = (LPNMHDR)lParam; + LRESULT lRet = 0; + + // pass toolbar custom draw notifications to the base class + if(lpnmh->code == NM_CUSTOMDRAW && lpnmh->hwndFrom == m_tb.m_hWnd) + lRet = CCustomDraw< T >::OnCustomDraw(0, lpnmh, bHandled); +#ifndef _WIN32_WCE + // tooltip notifications come with the tooltip window handle and button ID, + // pass them to the parent if we don't handle them + else if(lpnmh->code == TTN_GETDISPINFO && lpnmh->idFrom == pT->m_nCloseBtnID) + bHandled = pT->GetToolTipText(lpnmh); +#endif // !_WIN32_WCE + // only let notifications not from the toolbar go to the parent + else if(lpnmh->hwndFrom != m_tb.m_hWnd && lpnmh->idFrom != pT->m_nCloseBtnID) + bHandled = FALSE; + + return lRet; + } + + LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + // if command comes from the close button, substitute HWND of the pane container instead + if(m_tb.m_hWnd != NULL && (HWND)lParam == m_tb.m_hWnd) + return ::SendMessage(GetParent(), WM_COMMAND, wParam, (LPARAM)m_hWnd); + + bHandled = FALSE; + return 1; + } + +// Custom draw overrides + DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_NOTIFYITEMDRAW; // we need per-item notifications + } + + DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw) + { + CDCHandle dc = lpNMCustomDraw->hdc; +#if (_WIN32_IE >= 0x0400) + RECT& rc = lpNMCustomDraw->rc; +#else // !(_WIN32_IE >= 0x0400) + RECT rc; + m_tb.GetItemRect(0, &rc); +#endif // !(_WIN32_IE >= 0x0400) + + dc.FillRect(&rc, COLOR_3DFACE); + + return CDRF_NOTIFYPOSTPAINT; + } + + DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw) + { + CDCHandle dc = lpNMCustomDraw->hdc; +#if (_WIN32_IE >= 0x0400) + RECT& rc = lpNMCustomDraw->rc; +#else // !(_WIN32_IE >= 0x0400) + RECT rc = { 0 }; + m_tb.GetItemRect(0, &rc); +#endif // !(_WIN32_IE >= 0x0400) + + RECT rcImage = { m_xBtnImageLeft, m_yBtnImageTop, m_xBtnImageRight + 1, m_yBtnImageBottom + 1 }; + ::OffsetRect(&rcImage, rc.left, rc.top); + T* pT = static_cast(this); + + if((lpNMCustomDraw->uItemState & CDIS_DISABLED) != 0) + { + RECT rcShadow = rcImage; + ::OffsetRect(&rcShadow, 1, 1); + CPen pen1; + pen1.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT)); + pT->DrawButtonImage(dc, rcShadow, pen1); + CPen pen2; + pen2.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW)); + pT->DrawButtonImage(dc, rcImage, pen2); + } + else + { + if((lpNMCustomDraw->uItemState & CDIS_SELECTED) != 0) + ::OffsetRect(&rcImage, 1, 1); + CPen pen; + pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT)); + pT->DrawButtonImage(dc, rcImage, pen); + } + + return CDRF_DODEFAULT; // continue with the default item painting + } + +// Implementation - overrideable methods + void UpdateLayout(int cxWidth, int cyHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + RECT rect = { 0 }; + + if(IsVertical()) + { + ::SetRect(&rect, 0, 0, m_cxyHeader, cyHeight); + if(m_tb.m_hWnd != NULL) + m_tb.SetWindowPos(NULL, m_cxyBorder, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetWindowPos(NULL, m_cxyHeader, 0, cxWidth - m_cxyHeader, cyHeight, SWP_NOZORDER); + else + rect.right = cxWidth; + } + else + { + ::SetRect(&rect, 0, 0, cxWidth, m_cxyHeader); + if(m_tb.m_hWnd != NULL) + m_tb.SetWindowPos(NULL, rect.right - m_cxToolBar, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetWindowPos(NULL, 0, m_cxyHeader, cxWidth, cyHeight - m_cxyHeader, SWP_NOZORDER); + else + rect.bottom = cyHeight; + } + + InvalidateRect(&rect); + } + + void CreateCloseButton() + { + ATLASSERT(m_tb.m_hWnd == NULL); + // create toolbar for the "x" button + m_tb.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NOMOVEY | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 0); + ATLASSERT(m_tb.IsWindow()); + + if(m_tb.m_hWnd != NULL) + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + + m_tb.SetButtonStructSize(); + + TBBUTTON tbbtn = { 0 }; + tbbtn.idCommand = pT->m_nCloseBtnID; + tbbtn.fsState = TBSTATE_ENABLED; + tbbtn.fsStyle = TBSTYLE_BUTTON; + m_tb.AddButtons(1, &tbbtn); + + m_tb.SetBitmapSize(m_cxImageTB, m_cyImageTB); + m_tb.SetButtonSize(m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB); + + if(IsVertical()) + m_tb.SetWindowPos(NULL, m_cxyBorder + m_cxyBtnOffset, m_cxyBorder + m_cxyBtnOffset, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOACTIVATE); + else + m_tb.SetWindowPos(NULL, 0, 0, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + } + } + + void DestroyCloseButton() + { + if(m_tb.m_hWnd != NULL) + m_tb.DestroyWindow(); + } + + void CalcSize() + { + T* pT = static_cast(this); + CFontHandle font = pT->GetTitleFont(); + LOGFONT lf = { 0 }; + font.GetLogFont(lf); + if(IsVertical()) + { + m_cxyHeader = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder; + } + else + { + int cyFont = abs(lf.lfHeight) + m_cxyBorder + 2 * m_cxyTextOffset; + int cyBtn = m_cyImageTB + m_cxyBtnAddTB + m_cxyBorder + 2 * m_cxyBtnOffset; + m_cxyHeader = max(cyFont, cyBtn); + } + } + + HFONT GetTitleFont() const + { + return AtlGetDefaultGuiFont(); + } + +#ifndef _WIN32_WCE + BOOL GetToolTipText(LPNMHDR /*lpnmh*/) + { + return FALSE; + } +#endif // !_WIN32_WCE + + void DrawPaneTitle(CDCHandle dc) + { + RECT rect = { 0 }; + GetClientRect(&rect); + + UINT uBorder = BF_LEFT | BF_TOP | BF_ADJUST; + if(IsVertical()) + { + rect.right = rect.left + m_cxyHeader; + uBorder |= BF_BOTTOM; + } + else + { + rect.bottom = rect.top + m_cxyHeader; + uBorder |= BF_RIGHT; + } + + if((m_dwExtendedStyle & PANECNT_NOBORDER) == 0) + { + if((m_dwExtendedStyle & PANECNT_FLATBORDER) != 0) + uBorder |= BF_FLAT; + dc.DrawEdge(&rect, EDGE_ETCHED, uBorder); + } + dc.FillRect(&rect, COLOR_3DFACE); + + if(!IsVertical()) // draw title only for horizontal pane container + { + dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); + dc.SetBkMode(TRANSPARENT); + T* pT = static_cast(this); + HFONT hFontOld = dc.SelectFont(pT->GetTitleFont()); + rect.left += m_cxyTextOffset; + rect.right -= m_cxyTextOffset; + if(m_tb.m_hWnd != NULL) + rect.right -= m_cxToolBar;; +#ifndef _WIN32_WCE + dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); +#else // CE specific + dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER); +#endif // _WIN32_WCE + dc.SelectFont(hFontOld); + } + } + + // called only if pane is empty + void DrawPane(CDCHandle dc) + { + RECT rect = { 0 }; + GetClientRect(&rect); + if(IsVertical()) + rect.left += m_cxyHeader; + else + rect.top += m_cxyHeader; + if((GetExStyle() & WS_EX_CLIENTEDGE) == 0) + dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + dc.FillRect(&rect, COLOR_APPWORKSPACE); + } + + // drawing helper - draws "x" button image + void DrawButtonImage(CDCHandle dc, RECT& rcImage, HPEN hPen) + { +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + HPEN hPenOld = dc.SelectPen(hPen); + + dc.MoveTo(rcImage.left, rcImage.top); + dc.LineTo(rcImage.right, rcImage.bottom); + dc.MoveTo(rcImage.left + 1, rcImage.top); + dc.LineTo(rcImage.right + 1, rcImage.bottom); + + dc.MoveTo(rcImage.left, rcImage.bottom - 1); + dc.LineTo(rcImage.right, rcImage.top - 1); + dc.MoveTo(rcImage.left + 1, rcImage.bottom - 1); + dc.LineTo(rcImage.right + 1, rcImage.top - 1); + + dc.SelectPen(hPenOld); +#else // (_WIN32_WCE < 400) + rcImage; + hPen; + // no support for the "x" button image +#endif // (_WIN32_WCE < 400) + } + + bool IsVertical() const + { + return ((m_dwExtendedStyle & PANECNT_VERTICAL) != 0); + } +}; + +class CPaneContainer : public CPaneContainerImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_PaneContainer"), 0, -1) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CSortListViewCtrl - implements sorting for a listview control + +// sort listview extended styles +#define SORTLV_USESHELLBITMAPS 0x00000001 + +// Notification sent to parent when sort column is changed by user clicking header. +#define SLVN_SORTCHANGED LVN_LAST + +// A LPNMSORTLISTVIEW is sent with the SLVN_SORTCHANGED notification +typedef struct tagNMSORTLISTVIEW +{ + NMHDR hdr; + int iNewSortColumn; + int iOldSortColumn; +} NMSORTLISTVIEW, *LPNMSORTLISTVIEW; + +// Column sort types. Can be set on a per-column basis with the SetColumnSortType method. +enum +{ + LVCOLSORT_NONE, + LVCOLSORT_TEXT, // default + LVCOLSORT_TEXTNOCASE, + LVCOLSORT_LONG, + LVCOLSORT_DOUBLE, + LVCOLSORT_DECIMAL, + LVCOLSORT_DATETIME, + LVCOLSORT_DATE, + LVCOLSORT_TIME, + LVCOLSORT_CUSTOM, + LVCOLSORT_LAST = LVCOLSORT_CUSTOM +}; + + +template +class CSortListViewImpl +{ +public: + enum + { + m_cchCmpTextMax = 32, // overrideable + m_cxSortImage = 16, + m_cySortImage = 15, + m_cxSortArrow = 11, + m_cySortArrow = 6, + m_iSortUp = 0, // index of sort bitmaps + m_iSortDown = 1, + m_nShellSortUpID = 133 + }; + + // passed to LVCompare functions as lParam1 and lParam2 + struct LVCompareParam + { + int iItem; + DWORD_PTR dwItemData; + union + { + long lValue; + double dblValue; + DECIMAL decValue; + LPCTSTR pszValue; + }; + }; + + // passed to LVCompare functions as the lParamSort parameter + struct LVSortInfo + { + T* pT; + int iSortCol; + bool bDescending; + }; + + bool m_bSortDescending; + bool m_bCommCtrl6; + int m_iSortColumn; + CBitmap m_bmSort[2]; + int m_fmtOldSortCol; + HBITMAP m_hbmOldSortCol; + DWORD m_dwSortLVExtendedStyle; + ATL::CSimpleArray m_arrColSortType; + bool m_bUseWaitCursor; + + CSortListViewImpl() : + m_bSortDescending(false), + m_bCommCtrl6(false), + m_iSortColumn(-1), + m_fmtOldSortCol(0), + m_hbmOldSortCol(NULL), + m_dwSortLVExtendedStyle(SORTLV_USESHELLBITMAPS), + m_bUseWaitCursor(true) + { +#ifndef _WIN32_WCE + DWORD dwMajor = 0; + DWORD dwMinor = 0; + HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); + m_bCommCtrl6 = SUCCEEDED(hRet) && dwMajor >= 6; +#endif // !_WIN32_WCE + } + +// Attributes + void SetSortColumn(int iCol) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + CHeaderCtrl header = pT->GetHeader(); + ATLASSERT(header.m_hWnd != NULL); + ATLASSERT(iCol >= -1 && iCol < m_arrColSortType.GetSize()); + + int iOldSortCol = m_iSortColumn; + m_iSortColumn = iCol; + if(m_bCommCtrl6) + { +#ifndef HDF_SORTUP + const int HDF_SORTUP = 0x0400; +#endif // HDF_SORTUP +#ifndef HDF_SORTDOWN + const int HDF_SORTDOWN = 0x0200; +#endif // HDF_SORTDOWN + const int nMask = HDF_SORTUP | HDF_SORTDOWN; + HDITEM hditem = { HDI_FORMAT }; + if(iOldSortCol != iCol && iOldSortCol >= 0 && header.GetItem(iOldSortCol, &hditem)) + { + hditem.fmt &= ~nMask; + header.SetItem(iOldSortCol, &hditem); + } + if(iCol >= 0 && header.GetItem(iCol, &hditem)) + { + hditem.fmt &= ~nMask; + hditem.fmt |= m_bSortDescending ? HDF_SORTDOWN : HDF_SORTUP; + header.SetItem(iCol, &hditem); + } + return; + } + + if(m_bmSort[m_iSortUp].IsNull()) + pT->CreateSortBitmaps(); + + // restore previous sort column's bitmap, if any, and format + HDITEM hditem = { HDI_BITMAP | HDI_FORMAT }; + if(iOldSortCol != iCol && iOldSortCol >= 0) + { + hditem.hbm = m_hbmOldSortCol; + hditem.fmt = m_fmtOldSortCol; + header.SetItem(iOldSortCol, &hditem); + } + + // save new sort column's bitmap and format, and add our sort bitmap + if(iCol >= 0 && header.GetItem(iCol, &hditem)) + { + if(iOldSortCol != iCol) + { + m_fmtOldSortCol = hditem.fmt; + m_hbmOldSortCol = hditem.hbm; + } + hditem.fmt &= ~HDF_IMAGE; + hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT; + int i = m_bSortDescending ? m_iSortDown : m_iSortUp; + hditem.hbm = m_bmSort[i]; + header.SetItem(iCol, &hditem); + } + } + + int GetSortColumn() const + { + return m_iSortColumn; + } + + void SetColumnSortType(int iCol, WORD wType) + { + ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize()); + ATLASSERT(wType >= LVCOLSORT_NONE && wType <= LVCOLSORT_LAST); + m_arrColSortType[iCol] = wType; + } + + WORD GetColumnSortType(int iCol) const + { + ATLASSERT((iCol >= 0) && iCol < m_arrColSortType.GetSize()); + return m_arrColSortType[iCol]; + } + + int GetColumnCount() const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + CHeaderCtrl header = pT->GetHeader(); + return header.m_hWnd != NULL ? header.GetItemCount() : 0; + } + + bool IsSortDescending() const + { + return m_bSortDescending; + } + + DWORD GetSortListViewExtendedStyle() const + { + return m_dwSortLVExtendedStyle; + } + + DWORD SetSortListViewExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwSortLVExtendedStyle; + if(dwMask == 0) + m_dwSortLVExtendedStyle = dwExtendedStyle; + else + m_dwSortLVExtendedStyle = (m_dwSortLVExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + +// Operations + bool DoSortItems(int iCol, bool bDescending = false) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize()); + + WORD wType = m_arrColSortType[iCol]; + if(wType == LVCOLSORT_NONE) + return false; + + int nCount = pT->GetItemCount(); + if(nCount < 2) + { + m_bSortDescending = bDescending; + SetSortColumn(iCol); + return true; + } + + CWaitCursor waitCursor(false); + if(m_bUseWaitCursor) + waitCursor.Set(); + + LVCompareParam* pParam = NULL; + ATLTRY(pParam = new LVCompareParam[nCount]); + PFNLVCOMPARE pFunc = NULL; + TCHAR pszTemp[pT->m_cchCmpTextMax]; + bool bStrValue = false; + + switch(wType) + { + case LVCOLSORT_TEXT: + pFunc = (PFNLVCOMPARE)pT->LVCompareText; + case LVCOLSORT_TEXTNOCASE: + if(pFunc == NULL) + pFunc = (PFNLVCOMPARE)pT->LVCompareTextNoCase; + case LVCOLSORT_CUSTOM: + { + if(pFunc == NULL) + pFunc = (PFNLVCOMPARE)pT->LVCompareCustom; + + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pParam[i].pszValue = new TCHAR[pT->m_cchCmpTextMax]; + pT->GetItemText(i, iCol, (LPTSTR)pParam[i].pszValue, pT->m_cchCmpTextMax); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + bStrValue = true; + } + break; + case LVCOLSORT_LONG: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareLong; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pParam[i].lValue = pT->StrToLong(pszTemp); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + case LVCOLSORT_DOUBLE: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareDouble; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pParam[i].dblValue = pT->StrToDouble(pszTemp); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + case LVCOLSORT_DECIMAL: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareDecimal; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pT->StrToDecimal(pszTemp, &pParam[i].decValue); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + case LVCOLSORT_DATETIME: + case LVCOLSORT_DATE: + case LVCOLSORT_TIME: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareDouble; + DWORD dwFlags = LOCALE_NOUSEROVERRIDE; + if(wType == LVCOLSORT_DATE) + dwFlags |= VAR_DATEVALUEONLY; + else if(wType == LVCOLSORT_TIME) + dwFlags |= VAR_TIMEVALUEONLY; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pParam[i].dblValue = pT->DateStrToDouble(pszTemp, dwFlags); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("Unknown value for sort type in CSortListViewImpl::DoSortItems()\n")); + break; + } // switch(wType) + + ATLASSERT(pFunc != NULL); + LVSortInfo lvsi = { pT, iCol, bDescending }; + bool bRet = ((BOOL)pT->DefWindowProc(LVM_SORTITEMS, (WPARAM)&lvsi, (LPARAM)pFunc) != FALSE); + for(int i = 0; i < nCount; i++) + { + DWORD_PTR dwItemData = pT->GetItemData(i); + LVCompareParam* p = (LVCompareParam*)dwItemData; + ATLASSERT(p != NULL); + if(bStrValue) + delete [] (TCHAR*)p->pszValue; + pT->SetItemData(i, p->dwItemData); + } + delete [] pParam; + + if(bRet) + { + m_bSortDescending = bDescending; + SetSortColumn(iCol); + } + + if(m_bUseWaitCursor) + waitCursor.Restore(); + + return bRet; + } + + void CreateSortBitmaps() + { + if((m_dwSortLVExtendedStyle & SORTLV_USESHELLBITMAPS) != 0) + { + bool bFree = false; + LPCTSTR pszModule = _T("shell32.dll"); + HINSTANCE hShell = ::GetModuleHandle(pszModule); + + if (hShell == NULL) + { + hShell = ::LoadLibrary(pszModule); + bFree = true; + } + + if (hShell != NULL) + { + bool bSuccess = true; + for(int i = m_iSortUp; i <= m_iSortDown; i++) + { + if(!m_bmSort[i].IsNull()) + m_bmSort[i].DeleteObject(); + m_bmSort[i] = (HBITMAP)::LoadImage(hShell, MAKEINTRESOURCE(m_nShellSortUpID + i), +#ifndef _WIN32_WCE + IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); +#else // CE specific + IMAGE_BITMAP, 0, 0, 0); +#endif // _WIN32_WCE + if(m_bmSort[i].IsNull()) + { + bSuccess = false; + break; + } + } + if(bFree) + ::FreeLibrary(hShell); + if(bSuccess) + return; + } + } + + T* pT = static_cast(this); + for(int i = m_iSortUp; i <= m_iSortDown; i++) + { + if(!m_bmSort[i].IsNull()) + m_bmSort[i].DeleteObject(); + + CDC dcMem; + CClientDC dc(::GetDesktopWindow()); + dcMem.CreateCompatibleDC(dc.m_hDC); + m_bmSort[i].CreateCompatibleBitmap(dc.m_hDC, m_cxSortImage, m_cySortImage); + HBITMAP hbmOld = dcMem.SelectBitmap(m_bmSort[i]); + RECT rc = {0,0,m_cxSortImage, m_cySortImage}; + pT->DrawSortBitmap(dcMem.m_hDC, i, &rc); + dcMem.SelectBitmap(hbmOld); + dcMem.DeleteDC(); + } + } + + void NotifyParentSortChanged(int iNewSortCol, int iOldSortCol) + { + T* pT = static_cast(this); + int nID = pT->GetDlgCtrlID(); + NMSORTLISTVIEW nm = { { pT->m_hWnd, nID, SLVN_SORTCHANGED }, iNewSortCol, iOldSortCol }; + ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nm); + } + +// Overrideables + int CompareItemsCustom(LVCompareParam* /*pItem1*/, LVCompareParam* /*pItem2*/, int /*iSortCol*/) + { + // pItem1 and pItem2 contain valid iItem, dwItemData, and pszValue members. + // If item1 > item2 return 1, if item1 < item2 return -1, else return 0. + return 0; + } + + void DrawSortBitmap(CDCHandle dc, int iBitmap, LPRECT prc) + { + dc.FillRect(prc, ::GetSysColorBrush(COLOR_BTNFACE)); + HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW)); + CPen pen; + pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW)); + HPEN hpenOld = dc.SelectPen(pen); + POINT ptOrg = { (m_cxSortImage - m_cxSortArrow) / 2, (m_cySortImage - m_cySortArrow) / 2 }; + if(iBitmap == m_iSortUp) + { + POINT pts[3] = + { + { ptOrg.x + m_cxSortArrow / 2, ptOrg.y }, + { ptOrg.x, ptOrg.y + m_cySortArrow - 1 }, + { ptOrg.x + m_cxSortArrow - 1, ptOrg.y + m_cySortArrow - 1 } + }; + dc.Polygon(pts, 3); + } + else + { + POINT pts[3] = + { + { ptOrg.x, ptOrg.y }, + { ptOrg.x + m_cxSortArrow / 2, ptOrg.y + m_cySortArrow - 1 }, + { ptOrg.x + m_cxSortArrow - 1, ptOrg.y } + }; + dc.Polygon(pts, 3); + } + dc.SelectBrush(hbrOld); + dc.SelectPen(hpenOld); + } + + double DateStrToDouble(LPCTSTR lpstr, DWORD dwFlags) + { + ATLASSERT(lpstr != NULL); + if(lpstr == NULL || lpstr[0] == _T('\0')) + return 0; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + DATE dRet = 0; + if (FAILED(hRet = ::VarDateFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, dwFlags, &dRet))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarDateFromStr failed with result of 0x%8.8X\n"), hRet); + dRet = 0; + } + return dRet; + } + + long StrToLong(LPCTSTR lpstr) + { + ATLASSERT(lpstr != NULL); + if(lpstr == NULL || lpstr[0] == _T('\0')) + return 0; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + long lRet = 0; + if (FAILED(hRet = ::VarI4FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &lRet))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarI4FromStr failed with result of 0x%8.8X\n"), hRet); + lRet = 0; + } + return lRet; + } + + double StrToDouble(LPCTSTR lpstr) + { + ATLASSERT(lpstr != NULL); + if(lpstr == NULL || lpstr[0] == _T('\0')) + return 0; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + double dblRet = 0; + if (FAILED(hRet = ::VarR8FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &dblRet))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarR8FromStr failed with result of 0x%8.8X\n"), hRet); + dblRet = 0; + } + return dblRet; + } + + bool StrToDecimal(LPCTSTR lpstr, DECIMAL* pDecimal) + { + ATLASSERT(lpstr != NULL); + ATLASSERT(pDecimal != NULL); + if(lpstr == NULL || pDecimal == NULL) + return false; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + if (FAILED(hRet = ::VarDecFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, pDecimal))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarDecFromStr failed with result of 0x%8.8X\n"), hRet); + pDecimal->Lo64 = 0; + pDecimal->Hi32 = 0; + pDecimal->signscale = 0; + return false; + } + return true; + } + +// Overrideable PFNLVCOMPARE functions + static int CALLBACK LVCompareText(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = lstrcmp(pParam1->pszValue, pParam2->pszValue); + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareTextNoCase(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = lstrcmpi(pParam1->pszValue, pParam2->pszValue); + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareLong(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = 0; + if(pParam1->lValue > pParam2->lValue) + nRet = 1; + else if(pParam1->lValue < pParam2->lValue) + nRet = -1; + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareDouble(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = 0; + if(pParam1->dblValue > pParam2->dblValue) + nRet = 1; + else if(pParam1->dblValue < pParam2->dblValue) + nRet = -1; + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareCustom(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = pInfo->pT->CompareItemsCustom(pParam1, pParam2, pInfo->iSortCol); + return pInfo->bDescending ? -nRet : nRet; + } + +#ifndef _WIN32_WCE + static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = (int)::VarDecCmp(&pParam1->decValue, &pParam2->decValue); + nRet--; + return pInfo->bDescending ? -nRet : nRet; + } +#else + // Compare mantissas, ignore sign and scale + static int CompareMantissas(const DECIMAL& decLeft, const DECIMAL& decRight) + { + if (decLeft.Hi32 < decRight.Hi32) + { + return -1; + } + if (decLeft.Hi32 > decRight.Hi32) + { + return 1; + } + // Here, decLeft.Hi32 == decRight.Hi32 + if (decLeft.Lo64 < decRight.Lo64) + { + return -1; + } + if (decLeft.Lo64 > decRight.Lo64) + { + return 1; + } + return 0; + } + + // return values: VARCMP_LT, VARCMP_EQ, VARCMP_GT, VARCMP_NULL + static HRESULT VarDecCmp(const DECIMAL* pdecLeft, const DECIMAL* pdecRight) + { + static const ULONG powersOfTen[] = + { + 10ul, + 100ul, + 1000ul, + 10000ul, + 100000ul, + 1000000ul, + 10000000ul, + 100000000ul, + 1000000000ul + }; + static const int largestPower = sizeof(powersOfTen) / sizeof(powersOfTen[0]); + if (!pdecLeft || !pdecRight) + { + return VARCMP_NULL; + } + + // Degenerate case - at least one comparand is of the form + // [+-]0*10^N (denormalized zero) + bool bLeftZero = (!pdecLeft->Lo64 && !pdecLeft->Hi32); + bool bRightZero = (!pdecRight->Lo64 && !pdecRight->Hi32); + if (bLeftZero && bRightZero) + { + return VARCMP_EQ; + } + bool bLeftNeg = ((pdecLeft->sign & DECIMAL_NEG) != 0); + bool bRightNeg = ((pdecRight->sign & DECIMAL_NEG) != 0); + if (bLeftZero) + { + return (bRightNeg ? VARCMP_GT : VARCMP_LT); + } + // This also covers the case where the comparands have different signs + if (bRightZero || bLeftNeg != bRightNeg) + { + return (bLeftNeg ? VARCMP_LT : VARCMP_GT); + } + + // Here both comparands have the same sign and need to be compared + // on mantissa and scale. The result is obvious when + // 1. Scales are equal (then compare mantissas) + // 2. A number with smaller scale is also the one with larger mantissa + // (then this number is obviously larger) + // In the remaining case, we would multiply the number with smaller + // scale by 10 and simultaneously increment its scale (which amounts to + // adding trailing zeros after decimal point), until the numbers fall under + // one of the two cases above + DECIMAL temp; + bool bInvert = bLeftNeg; // the final result needs to be inverted + if (pdecLeft->scale < pdecRight->scale) + { + temp = *pdecLeft; + } + else + { + temp = *pdecRight; + pdecRight = pdecLeft; + bInvert = !bInvert; + } + + // Now temp is the number with smaller (or equal) scale, and + // we can modify it freely without touching original parameters + int comp; + while ((comp = CompareMantissas(temp, *pdecRight)) < 0 && + temp.scale < pdecRight->scale) + { + // Multiply by an appropriate power of 10 + int scaleDiff = pdecRight->scale - temp.scale; + if (scaleDiff > largestPower) + { + // Keep the multiplier representable in 32bit + scaleDiff = largestPower; + } + DWORDLONG power = powersOfTen[scaleDiff - 1]; + // Multiply temp's mantissa by power + DWORDLONG product = temp.Lo32 * power; + ULONG carry = static_cast(product >> 32); + temp.Lo32 = static_cast(product); + product = temp.Mid32 * power + carry; + carry = static_cast(product >> 32); + temp.Mid32 = static_cast(product); + product = temp.Hi32 * power + carry; + if (static_cast(product >> 32)) + { + // Multiplication overflowed - pdecLeft is clearly larger + break; + } + temp.Hi32 = static_cast(product); + temp.scale = (BYTE)(temp.scale + scaleDiff); + } + if (temp.scale < pdecRight->scale) + { + comp = 1; + } + if (bInvert) + { + comp = -comp; + } + return (comp > 0 ? VARCMP_GT : comp < 0 ? VARCMP_LT : VARCMP_EQ); + } + + static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = (int)VarDecCmp(&pParam1->decValue, &pParam2->decValue); + nRet--; + return pInfo->bDescending ? -nRet : nRet; + } +#endif // !_WIN32_WCE + + BEGIN_MSG_MAP(CSortListViewImpl) + MESSAGE_HANDLER(LVM_INSERTCOLUMN, OnInsertColumn) + MESSAGE_HANDLER(LVM_DELETECOLUMN, OnDeleteColumn) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, OnHeaderItemClick) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, OnHeaderItemClick) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + END_MSG_MAP() + + LRESULT OnInsertColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); + if(lRet == -1) + return -1; + + WORD wType = 0; + m_arrColSortType.Add(wType); + int nCount = m_arrColSortType.GetSize(); + ATLASSERT(nCount == GetColumnCount()); + + for(int i = nCount - 1; i > lRet; i--) + m_arrColSortType[i] = m_arrColSortType[i - 1]; + m_arrColSortType[(int)lRet] = LVCOLSORT_TEXT; + + if(lRet <= m_iSortColumn) + m_iSortColumn++; + + return lRet; + } + + LRESULT OnDeleteColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); + if(lRet == 0) + return 0; + + int iCol = (int)wParam; + if(m_iSortColumn == iCol) + m_iSortColumn = -1; + else if(m_iSortColumn > iCol) + m_iSortColumn--; + m_arrColSortType.RemoveAt(iCol); + + return lRet; + } + + LRESULT OnHeaderItemClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + LPNMHEADER p = (LPNMHEADER)pnmh; + if(p->iButton == 0) + { + int iOld = m_iSortColumn; + bool bDescending = (m_iSortColumn == p->iItem) ? !m_bSortDescending : false; + if(DoSortItems(p->iItem, bDescending)) + NotifyParentSortChanged(p->iItem, iOld); + } + bHandled = FALSE; + return 0; + } + + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifndef _WIN32_WCE + if(wParam == SPI_SETNONCLIENTMETRICS) + GetSystemSettings(); +#else // CE specific + wParam; // avoid level 4 warning + GetSystemSettings(); +#endif // _WIN32_WCE + bHandled = FALSE; + return 0; + } + + void GetSystemSettings() + { + if(!m_bCommCtrl6 && !m_bmSort[m_iSortUp].IsNull()) + { + T* pT = static_cast(this); + pT->CreateSortBitmaps(); + if(m_iSortColumn != -1) + SetSortColumn(m_iSortColumn); + } + } + +}; + + +typedef ATL::CWinTraits CSortListViewCtrlTraits; + +template +class ATL_NO_VTABLE CSortListViewCtrlImpl: public ATL::CWindowImpl, public CSortListViewImpl +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + + bool SortItems(int iCol, bool bDescending = false) + { + return DoSortItems(iCol, bDescending); + } + + BEGIN_MSG_MAP(CSortListViewCtrlImpl) + MESSAGE_HANDLER(LVM_INSERTCOLUMN, CSortListViewImpl::OnInsertColumn) + MESSAGE_HANDLER(LVM_DELETECOLUMN, CSortListViewImpl::OnDeleteColumn) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, CSortListViewImpl::OnHeaderItemClick) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, CSortListViewImpl::OnHeaderItemClick) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CSortListViewImpl::OnSettingChange) + END_MSG_MAP() +}; + +class CSortListViewCtrl : public CSortListViewCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_SortListViewCtrl"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CTabView - implements tab view window + +// TabView Notifications +#define TBVN_PAGEACTIVATED (0U-741) +#define TBVN_CONTEXTMENU (0U-742) + +// Notification data for TBVN_CONTEXTMENU +struct TBVCONTEXTMENUINFO +{ + NMHDR hdr; + POINT pt; +}; + +typedef TBVCONTEXTMENUINFO* LPTBVCONTEXTMENUINFO; + + +template +class ATL_NO_VTABLE CTabViewImpl : public ATL::CWindowImpl +{ +public: + DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE) + +// Declarations and enums + struct TABVIEWPAGE + { + HWND hWnd; + LPTSTR lpstrTitle; + LPVOID pData; + }; + + struct TCITEMEXTRA + { + TCITEMHEADER tciheader; + TABVIEWPAGE tvpage; + + operator LPTCITEM() { return (LPTCITEM)this; } + }; + + enum + { + m_nTabID = 1313, + m_cxMoveMark = 6, + m_cyMoveMark = 3, + m_nMenuItemsMax = (ID_WINDOW_TABLAST - ID_WINDOW_TABFIRST + 1) + }; + +// Data members + ATL::CContainedWindowT m_tab; + int m_cyTabHeight; + + int m_nActivePage; + + int m_nInsertItem; + POINT m_ptStartDrag; + + CMenuHandle m_menu; + + int m_cchTabTextLength; + + int m_nMenuItemsCount; + + ATL::CWindow m_wndTitleBar; + LPTSTR m_lpstrTitleBarBase; + int m_cchTitleBarLength; + + CImageList m_ilDrag; + + bool m_bDestroyPageOnRemove:1; + bool m_bDestroyImageList:1; + bool m_bActivePageMenuItem:1; + bool m_bActiveAsDefaultMenuItem:1; + bool m_bEmptyMenuItem:1; + bool m_bWindowsMenuItem:1; + // internal + bool m_bTabCapture:1; + bool m_bTabDrag:1; + +// Constructor/destructor + CTabViewImpl() : + m_nActivePage(-1), + m_cyTabHeight(0), + m_tab(this, 1), + m_nInsertItem(-1), + m_cchTabTextLength(30), + m_nMenuItemsCount(10), + m_lpstrTitleBarBase(NULL), + m_cchTitleBarLength(100), + m_bDestroyPageOnRemove(true), + m_bDestroyImageList(true), + m_bActivePageMenuItem(true), + m_bActiveAsDefaultMenuItem(false), + m_bEmptyMenuItem(false), + m_bWindowsMenuItem(false), + m_bTabCapture(false), + m_bTabDrag(false) + { + m_ptStartDrag.x = 0; + m_ptStartDrag.y = 0; + } + + ~CTabViewImpl() + { + delete [] m_lpstrTitleBarBase; + } + +// Message filter function - to be called from PreTranslateMessage of the main window + BOOL PreTranslateMessage(MSG* pMsg) + { + if(IsWindow() == FALSE) + return FALSE; + + BOOL bRet = FALSE; + + // Check for TabView built-in accelerators (Ctrl+Tab/Ctrl+Shift+Tab - next/previous page) + int nCount = GetPageCount(); + if(nCount > 0) + { + bool bControl = (::GetKeyState(VK_CONTROL) < 0); + if((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) && bControl) + { + if(nCount > 1) + { + int nPage = m_nActivePage; + bool bShift = (::GetKeyState(VK_SHIFT) < 0); + if(bShift) + nPage = (nPage > 0) ? (nPage - 1) : (nCount - 1); + else + nPage = ((nPage >= 0) && (nPage < (nCount - 1))) ? (nPage + 1) : 0; + + SetActivePage(nPage); + T* pT = static_cast(this); + pT->OnPageActivated(m_nActivePage); + } + + bRet = TRUE; + } + } + + // If we are doing drag-drop, check for Escape key that cancels it + if(bRet == FALSE) + { + if(m_bTabCapture && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) + { + ::ReleaseCapture(); + bRet = TRUE; + } + } + + // Pass the message to the active page + if(bRet == FALSE) + { + if(m_nActivePage != -1) + bRet = (BOOL)::SendMessage(GetPageHWND(m_nActivePage), WM_FORWARDMSG, 0, (LPARAM)pMsg); + } + + return bRet; + } + +// Attributes + int GetPageCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_tab.GetItemCount(); + } + + int GetActivePage() const + { + return m_nActivePage; + } + + void SetActivePage(int nPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + SetRedraw(FALSE); + + if(m_nActivePage != -1) + ::ShowWindow(GetPageHWND(m_nActivePage), FALSE); + m_nActivePage = nPage; + m_tab.SetCurSel(m_nActivePage); + ::ShowWindow(GetPageHWND(m_nActivePage), TRUE); + + pT->UpdateLayout(); + + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + + if(::GetFocus() != m_tab.m_hWnd) + ::SetFocus(GetPageHWND(m_nActivePage)); + + pT->UpdateTitleBar(); + pT->UpdateMenu(); + } + + HIMAGELIST GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_tab.GetImageList(); + } + + HIMAGELIST SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_tab.SetImageList(hImageList); + } + + void SetWindowMenu(HMENU hMenu) + { + ATLASSERT(::IsWindow(m_hWnd)); + + m_menu = hMenu; + + T* pT = static_cast(this); + pT->UpdateMenu(); + } + + void SetTitleBarWindow(HWND hWnd) + { + ATLASSERT(::IsWindow(m_hWnd)); + + delete [] m_lpstrTitleBarBase; + m_lpstrTitleBarBase = NULL; + + m_wndTitleBar = hWnd; + if(hWnd == NULL) + return; + + int cchLen = m_wndTitleBar.GetWindowTextLength() + 1; + ATLTRY(m_lpstrTitleBarBase = new TCHAR[cchLen]); + if(m_lpstrTitleBarBase != NULL) + { + m_wndTitleBar.GetWindowText(m_lpstrTitleBarBase, cchLen); + T* pT = static_cast(this); + pT->UpdateTitleBar(); + } + } + +// Page attributes + HWND GetPageHWND(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + m_tab.GetItem(nPage, tcix); + + return tcix.tvpage.hWnd; + } + + LPCTSTR GetPageTitle(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + if(m_tab.GetItem(nPage, tcix) == FALSE) + return NULL; + + return tcix.tvpage.lpstrTitle; + } + + bool SetPageTitle(int nPage, LPCTSTR lpstrTitle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + int cchBuff = lstrlen(lpstrTitle) + 1; + LPTSTR lpstrBuff = NULL; + ATLTRY(lpstrBuff = new TCHAR[cchBuff]); + if(lpstrBuff == NULL) + return false; + + SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle); + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + if(m_tab.GetItem(nPage, tcix) == FALSE) + return false; + + CTempBuffer buff; + LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); + if(lpstrTabText == NULL) + return false; + + delete [] tcix.tvpage.lpstrTitle; + + pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1); + + tcix.tciheader.mask = TCIF_TEXT | TCIF_PARAM; + tcix.tciheader.pszText = lpstrTabText; + tcix.tvpage.lpstrTitle = lpstrBuff; + if(m_tab.SetItem(nPage, tcix) == FALSE) + return false; + + pT->UpdateTitleBar(); + pT->UpdateMenu(); + + return true; + } + + LPVOID GetPageData(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + m_tab.GetItem(nPage, tcix); + + return tcix.tvpage.pData; + } + + LPVOID SetPageData(int nPage, LPVOID pData) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + m_tab.GetItem(nPage, tcix); + LPVOID pDataOld = tcix.tvpage.pData; + + tcix.tvpage.pData = pData; + m_tab.SetItem(nPage, tcix); + + return pDataOld; + } + + int GetPageImage(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_IMAGE; + m_tab.GetItem(nPage, tcix); + + return tcix.tciheader.iImage; + } + + int SetPageImage(int nPage, int nImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_IMAGE; + m_tab.GetItem(nPage, tcix); + int nImageOld = tcix.tciheader.iImage; + + tcix.tciheader.iImage = nImage; + m_tab.SetItem(nPage, tcix); + + return nImageOld; + } + +// Operations + bool AddPage(HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL) + { + return InsertPage(GetPageCount(), hWndView, lpstrTitle, nImage, pData); + } + + bool InsertPage(int nPage, HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPage == GetPageCount() || IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + int cchBuff = lstrlen(lpstrTitle) + 1; + LPTSTR lpstrBuff = NULL; + ATLTRY(lpstrBuff = new TCHAR[cchBuff]); + if(lpstrBuff == NULL) + return false; + + SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle); + + CTempBuffer buff; + LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); + if(lpstrTabText == NULL) + return false; + + pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1); + + SetRedraw(FALSE); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; + tcix.tciheader.pszText = lpstrTabText; + tcix.tciheader.iImage = nImage; + tcix.tvpage.hWnd = hWndView; + tcix.tvpage.lpstrTitle = lpstrBuff; + tcix.tvpage.pData = pData; + int nItem = m_tab.InsertItem(nPage, tcix); + if(nItem == -1) + { + delete [] lpstrBuff; + SetRedraw(TRUE); + return false; + } + + SetActivePage(nItem); + pT->OnPageActivated(m_nActivePage); + + if(GetPageCount() == 1) + pT->ShowTabControl(true); + + pT->UpdateLayout(); + + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + + return true; + } + + void RemovePage(int nPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + SetRedraw(FALSE); + + if(GetPageCount() == 1) + pT->ShowTabControl(false); + + if(m_bDestroyPageOnRemove) + ::DestroyWindow(GetPageHWND(nPage)); + else + ::ShowWindow(GetPageHWND(nPage), FALSE); + LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(nPage); + delete [] lpstrTitle; + + ATLVERIFY(m_tab.DeleteItem(nPage) != FALSE); + + if(m_nActivePage == nPage) + { + m_nActivePage = -1; + + if(nPage > 0) + { + SetActivePage(nPage - 1); + } + else if(GetPageCount() > 0) + { + SetActivePage(nPage); + } + else + { + SetRedraw(TRUE); + Invalidate(); + UpdateWindow(); + pT->UpdateTitleBar(); + pT->UpdateMenu(); + } + } + else + { + nPage = (nPage < m_nActivePage) ? (m_nActivePage - 1) : m_nActivePage; + m_nActivePage = -1; + SetActivePage(nPage); + } + + pT->OnPageActivated(m_nActivePage); + } + + void RemoveAllPages() + { + ATLASSERT(::IsWindow(m_hWnd)); + + if(GetPageCount() == 0) + return; + + T* pT = static_cast(this); + + SetRedraw(FALSE); + + pT->ShowTabControl(false); + + for(int i = 0; i < GetPageCount(); i++) + { + if(m_bDestroyPageOnRemove) + ::DestroyWindow(GetPageHWND(i)); + else + ::ShowWindow(GetPageHWND(i), FALSE); + LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(i); + delete [] lpstrTitle; + } + m_tab.DeleteAllItems(); + + m_nActivePage = -1; + pT->OnPageActivated(m_nActivePage); + + SetRedraw(TRUE); + Invalidate(); + UpdateWindow(); + + pT->UpdateTitleBar(); + pT->UpdateMenu(); + } + + int PageIndexFromHwnd(HWND hWnd) const + { + int nIndex = -1; + + for(int i = 0; i < GetPageCount(); i++) + { + if(GetPageHWND(i) == hWnd) + { + nIndex = i; + break; + } + } + + return nIndex; + } + + void BuildWindowMenu(HMENU hMenu, int nMenuItemsCount = 10, bool bEmptyMenuItem = true, bool bWindowsMenuItem = true, bool bActivePageMenuItem = true, bool bActiveAsDefaultMenuItem = false) + { + ATLASSERT(::IsWindow(m_hWnd)); + + CMenuHandle menu = hMenu; + T* pT = static_cast(this); + pT; // avoid level 4 warning + int nFirstPos = 0; + + // Find first menu item in our range +#ifndef _WIN32_WCE + for(nFirstPos = 0; nFirstPos < menu.GetMenuItemCount(); nFirstPos++) + { + UINT nID = menu.GetMenuItemID(nFirstPos); + if((nID >= ID_WINDOW_TABFIRST && nID <= ID_WINDOW_TABLAST) || nID == ID_WINDOW_SHOWTABLIST) + break; + } +#else // CE specific + for(nFirstPos = 0; ; nFirstPos++) + { + CMenuItemInfo mii; + mii.fMask = MIIM_ID; + BOOL bRet = menu.GetMenuItemInfo(nFirstPos, TRUE, &mii); + if(bRet == FALSE) + break; + if((mii.wID >= ID_WINDOW_TABFIRST && mii.wID <= ID_WINDOW_TABLAST) || mii.wID == ID_WINDOW_SHOWTABLIST) + break; + } +#endif // _WIN32_WCE + + // Remove all menu items for tab pages + BOOL bRet = TRUE; + while(bRet != FALSE) + bRet = menu.DeleteMenu(nFirstPos, MF_BYPOSITION); + + // Add separator if it's not already there + int nPageCount = GetPageCount(); + if((bWindowsMenuItem || (nPageCount > 0)) && (nFirstPos > 0)) + { + CMenuItemInfo mii; + mii.fMask = MIIM_TYPE; + menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii); + if((nFirstPos <= 0) || ((mii.fType & MFT_SEPARATOR) == 0)) + { + menu.AppendMenu(MF_SEPARATOR); + nFirstPos++; + } + } + + // Add menu items for all pages + if(nPageCount > 0) + { + // Append menu items for all pages + const int cchPrefix = 3; // 2 digits + space + nMenuItemsCount = min(min(nPageCount, nMenuItemsCount), (int)m_nMenuItemsMax); + ATLASSERT(nMenuItemsCount < 100); // 2 digits only + if(nMenuItemsCount >= 100) + nMenuItemsCount = 99; + + for(int i = 0; i < nMenuItemsCount; i++) + { + LPCTSTR lpstrTitle = GetPageTitle(i); + int nLen = lstrlen(lpstrTitle); + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(cchPrefix + nLen + 1); + ATLASSERT(lpstrText != NULL); + if(lpstrText != NULL) + { + LPCTSTR lpstrFormat = (i < 9) ? _T("&%i %s") : _T("%i %s"); + SecureHelper::wsprintf_x(lpstrText, cchPrefix + nLen + 1, lpstrFormat, i + 1, lpstrTitle); + menu.AppendMenu(MF_STRING, ID_WINDOW_TABFIRST + i, lpstrText); + } + } + + // Mark active page + if(bActivePageMenuItem && (m_nActivePage != -1)) + { +#ifndef _WIN32_WCE + if(bActiveAsDefaultMenuItem) + { + menu.SetMenuDefaultItem((UINT)-1, TRUE); + menu.SetMenuDefaultItem(nFirstPos + m_nActivePage, TRUE); + } + else +#else // CE specific + bActiveAsDefaultMenuItem; // avoid level 4 warning +#endif // _WIN32_WCE + { + menu.CheckMenuRadioItem(nFirstPos, nFirstPos + nMenuItemsCount, nFirstPos + m_nActivePage, MF_BYPOSITION); + } + } + } + else + { + if(bEmptyMenuItem) + { + menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_TABFIRST, pT->GetEmptyListText()); + menu.EnableMenuItem(ID_WINDOW_TABFIRST, MF_GRAYED); + } + + // Remove separator if nothing else is there + if(!bEmptyMenuItem && !bWindowsMenuItem && (nFirstPos > 0)) + { + CMenuItemInfo mii; + mii.fMask = MIIM_TYPE; + menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii); + if((mii.fType & MFT_SEPARATOR) != 0) + menu.DeleteMenu(nFirstPos - 1, MF_BYPOSITION); + } + } + + // Add "Windows..." menu item + if(bWindowsMenuItem) + menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_SHOWTABLIST, pT->GetWindowsMenuItemText()); + } + +// Message map and handlers + BEGIN_MSG_MAP(CTabViewImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + NOTIFY_HANDLER(m_nTabID, TCN_SELCHANGE, OnTabChanged) + NOTIFY_ID_HANDLER(m_nTabID, OnTabNotification) +#ifndef _WIN32_WCE + NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnTabGetDispInfo) +#endif // !_WIN32_WCE + FORWARD_NOTIFICATIONS() + ALT_MSG_MAP(1) // tab control + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnTabLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONUP, OnTabLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnTabCaptureChanged) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnTabMouseMove) + MESSAGE_HANDLER(WM_RBUTTONUP, OnTabRButtonUp) + MESSAGE_HANDLER(WM_SYSKEYDOWN, OnTabSysKeyDown) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->CreateTabControl(); + + return 0; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + RemoveAllPages(); + + if(m_bDestroyImageList) + { + CImageList il = m_tab.SetImageList(NULL); + if(il.m_hImageList != NULL) + il.Destroy(); + } + + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + return 0; + } + + LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_nActivePage != -1) + ::SetFocus(GetPageHWND(m_nActivePage)); + return 0; + } + + LRESULT OnTabChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + SetActivePage(m_tab.GetCurSel()); + T* pT = static_cast(this); + pT->OnPageActivated(m_nActivePage); + + return 0; + } + + LRESULT OnTabNotification(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + // nothing to do - this just blocks all tab control + // notifications from being propagated further + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnTabGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + LPNMTTDISPINFO pTTDI = (LPNMTTDISPINFO)pnmh; + if(pTTDI->hdr.hwndFrom == m_tab.GetTooltips()) + { + T* pT = static_cast(this); + pT->UpdateTooltipText(pTTDI); + } + else + { + bHandled = FALSE; + } + + return 0; + } +#endif // !_WIN32_WCE + +// Tab control message handlers + LRESULT OnTabLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_tab.GetItemCount() > 1) + { + m_bTabCapture = true; + m_tab.SetCapture(); + + m_ptStartDrag.x = GET_X_LPARAM(lParam); + m_ptStartDrag.y = GET_Y_LPARAM(lParam); + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnTabLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_bTabCapture) + { + if(m_bTabDrag) + { + TCHITTESTINFO hti = { 0 }; + hti.pt.x = GET_X_LPARAM(lParam); + hti.pt.y = GET_Y_LPARAM(lParam); + int nItem = m_tab.HitTest(&hti); + if(nItem != -1) + MovePage(m_nActivePage, nItem); + } + + ::ReleaseCapture(); + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnTabCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bTabCapture) + { + m_bTabCapture = false; + + if(m_bTabDrag) + { + m_bTabDrag = false; + T* pT = static_cast(this); + pT->DrawMoveMark(-1); + +#ifndef _WIN32_WCE + m_ilDrag.DragLeave(GetDesktopWindow()); +#endif // !_WIN32_WCE + m_ilDrag.EndDrag(); + + m_ilDrag.Destroy(); + m_ilDrag.m_hImageList = NULL; + } + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnTabMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + bHandled = FALSE; + + if(m_bTabCapture) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + + if(!m_bTabDrag) + { +#ifndef _WIN32_WCE + if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CXDRAG) || + abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CYDRAG)) +#else // CE specific + if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= 4 || + abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= 4) +#endif // _WIN32_WCE + { + T* pT = static_cast(this); + pT->GenerateDragImage(m_nActivePage); + + int cxCursor = ::GetSystemMetrics(SM_CXCURSOR); + int cyCursor = ::GetSystemMetrics(SM_CYCURSOR); + m_ilDrag.BeginDrag(0, -(cxCursor / 2), -(cyCursor / 2)); +#ifndef _WIN32_WCE + POINT ptEnter = m_ptStartDrag; + m_tab.ClientToScreen(&ptEnter); + m_ilDrag.DragEnter(GetDesktopWindow(), ptEnter); +#endif // !_WIN32_WCE + + m_bTabDrag = true; + } + } + + if(m_bTabDrag) + { + TCHITTESTINFO hti = { 0 }; + hti.pt = pt; + int nItem = m_tab.HitTest(&hti); + + T* pT = static_cast(this); + pT->SetMoveCursor(nItem != -1); + + if(m_nInsertItem != nItem) + pT->DrawMoveMark(nItem); + + m_ilDrag.DragShowNolock((nItem != -1) ? TRUE : FALSE); + m_tab.ClientToScreen(&pt); + m_ilDrag.DragMove(pt); + + bHandled = TRUE; + } + } + + return 0; + } + + LRESULT OnTabRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + TCHITTESTINFO hti = { 0 }; + hti.pt.x = GET_X_LPARAM(lParam); + hti.pt.y = GET_Y_LPARAM(lParam); + int nItem = m_tab.HitTest(&hti); + if(nItem != -1) + { + T* pT = static_cast(this); + pT->OnContextMenu(nItem, hti.pt); + } + + return 0; + } + + LRESULT OnTabSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bool bShift = (::GetKeyState(VK_SHIFT) < 0); + if(wParam == VK_F10 && bShift) + { + if(m_nActivePage != -1) + { + RECT rect = { 0 }; + m_tab.GetItemRect(m_nActivePage, &rect); + POINT pt = { rect.left, rect.bottom }; + T* pT = static_cast(this); + pT->OnContextMenu(m_nActivePage, pt); + } + } + else + { + bHandled = FALSE; + } + + return 0; + } + +// Implementation helpers + bool IsValidPageIndex(int nPage) const + { + return (nPage >= 0 && nPage < GetPageCount()); + } + + bool MovePage(int nMovePage, int nInsertBeforePage) + { + ATLASSERT(IsValidPageIndex(nMovePage)); + ATLASSERT(IsValidPageIndex(nInsertBeforePage)); + + if(!IsValidPageIndex(nMovePage) || !IsValidPageIndex(nInsertBeforePage)) + return false; + + if(nMovePage == nInsertBeforePage) + return true; // nothing to do + + CTempBuffer buff; + LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); + if(lpstrTabText == NULL) + return false; + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; + tcix.tciheader.pszText = lpstrTabText; + tcix.tciheader.cchTextMax = m_cchTabTextLength + 1; + BOOL bRet = m_tab.GetItem(nMovePage, tcix); + ATLASSERT(bRet != FALSE); + if(bRet == FALSE) + return false; + + int nInsertItem = (nInsertBeforePage > nMovePage) ? nInsertBeforePage + 1 : nInsertBeforePage; + int nNewItem = m_tab.InsertItem(nInsertItem, tcix); + ATLASSERT(nNewItem == nInsertItem); + if(nNewItem != nInsertItem) + { + ATLVERIFY(m_tab.DeleteItem(nNewItem)); + return false; + } + + if(nMovePage > nInsertBeforePage) + ATLVERIFY(m_tab.DeleteItem(nMovePage + 1) != FALSE); + else if(nMovePage < nInsertBeforePage) + ATLVERIFY(m_tab.DeleteItem(nMovePage) != FALSE); + + SetActivePage(nInsertBeforePage); + T* pT = static_cast(this); + pT->OnPageActivated(m_nActivePage); + + return true; + } + +// Implementation overrideables + bool CreateTabControl() + { +#ifndef _WIN32_WCE + m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_TOOLTIPS, 0, m_nTabID); +#else // CE specific + m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, m_nTabID); +#endif // _WIN32_WCE + ATLASSERT(m_tab.m_hWnd != NULL); + if(m_tab.m_hWnd == NULL) + return false; + + m_tab.SetFont(AtlGetDefaultGuiFont()); + + m_tab.SetItemExtra(sizeof(TABVIEWPAGE)); + + T* pT = static_cast(this); + m_cyTabHeight = pT->CalcTabHeight(); + + return true; + } + + int CalcTabHeight() + { + int nCount = m_tab.GetItemCount(); + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT; + tcix.tciheader.pszText = _T("NS"); + int nIndex = m_tab.InsertItem(nCount, tcix); + + RECT rect = { 0, 0, 1000, 1000 }; + m_tab.AdjustRect(FALSE, &rect); + + RECT rcWnd = { 0, 0, 1000, rect.top }; + ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle()); + + int nHeight = rcWnd.bottom - rcWnd.top; + + m_tab.DeleteItem(nIndex); + + return nHeight; + } + + void ShowTabControl(bool bShow) + { + m_tab.ShowWindow(bShow ? SW_SHOWNOACTIVATE : SW_HIDE); + } + + void UpdateLayout() + { + RECT rect; + GetClientRect(&rect); + + if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0)) + m_tab.SetWindowPos(NULL, 0, 0, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER); + + if(m_nActivePage != -1) + ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, m_cyTabHeight, rect.right - rect.left, rect.bottom - rect.top - m_cyTabHeight, SWP_NOZORDER); + } + + void UpdateMenu() + { + if(m_menu.m_hMenu != NULL) + BuildWindowMenu(m_menu, m_nMenuItemsCount, m_bEmptyMenuItem, m_bWindowsMenuItem, m_bActivePageMenuItem, m_bActiveAsDefaultMenuItem); + } + + void UpdateTitleBar() + { + if(!m_wndTitleBar.IsWindow() || m_lpstrTitleBarBase == NULL) + return; // nothing to do + + if(m_nActivePage != -1) + { + T* pT = static_cast(this); + LPCTSTR lpstrTitle = pT->GetPageTitle(m_nActivePage); + LPCTSTR lpstrDivider = pT->GetTitleDividerText(); + int cchBuffer = m_cchTitleBarLength + lstrlen(lpstrDivider) + lstrlen(m_lpstrTitleBarBase) + 1; + CTempBuffer buff; + LPTSTR lpstrPageTitle = buff.Allocate(cchBuffer); + ATLASSERT(lpstrPageTitle != NULL); + if(lpstrPageTitle != NULL) + { + pT->ShortenTitle(lpstrTitle, lpstrPageTitle, m_cchTitleBarLength + 1); + SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, lpstrDivider); + SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, m_lpstrTitleBarBase); + } + else + { + lpstrPageTitle = m_lpstrTitleBarBase; + } + + m_wndTitleBar.SetWindowText(lpstrPageTitle); + } + else + { + m_wndTitleBar.SetWindowText(m_lpstrTitleBarBase); + } + } + + void DrawMoveMark(int nItem) + { + T* pT = static_cast(this); + + if(m_nInsertItem != -1) + { + RECT rect = { 0 }; + pT->GetMoveMarkRect(rect); + m_tab.InvalidateRect(&rect); + } + + m_nInsertItem = nItem; + + if(m_nInsertItem != -1) + { + CClientDC dc(m_tab.m_hWnd); + + RECT rect = { 0 }; + pT->GetMoveMarkRect(rect); + + CPen pen; + pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWTEXT)); + CBrush brush; + brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT)); + + HPEN hPenOld = dc.SelectPen(pen); + HBRUSH hBrushOld = dc.SelectBrush(brush); + + int x = rect.left; + int y = rect.top; + POINT ptsTop[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y + m_cyMoveMark } }; + dc.Polygon(ptsTop, 3); + + y = rect.bottom - 1; + POINT ptsBottom[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y - m_cyMoveMark } }; + dc.Polygon(ptsBottom, 3); + + dc.SelectPen(hPenOld); + dc.SelectBrush(hBrushOld); + } + } + + void GetMoveMarkRect(RECT& rect) const + { + m_tab.GetClientRect(&rect); + + RECT rcItem = { 0 }; + m_tab.GetItemRect(m_nInsertItem, &rcItem); + + if(m_nInsertItem <= m_nActivePage) + { + rect.left = rcItem.left - m_cxMoveMark / 2 - 1; + rect.right = rcItem.left + m_cxMoveMark / 2; + } + else + { + rect.left = rcItem.right - m_cxMoveMark / 2 - 1; + rect.right = rcItem.right + m_cxMoveMark / 2; + } + } + + void SetMoveCursor(bool bCanMove) + { + ::SetCursor(::LoadCursor(NULL, bCanMove ? IDC_ARROW : IDC_NO)); + } + + void GenerateDragImage(int nItem) + { + ATLASSERT(IsValidPageIndex(nItem)); + +#ifndef _WIN32_WCE + RECT rcItem = { 0 }; + m_tab.GetItemRect(nItem, &rcItem); + ::InflateRect(&rcItem, 2, 2); // make bigger to cover selected item +#else // CE specific + nItem; // avoid level 4 warning + RECT rcItem = { 0, 0, 40, 20 }; +#endif // _WIN32_WCE + + ATLASSERT(m_ilDrag.m_hImageList == NULL); + m_ilDrag.Create(rcItem.right - rcItem.left, rcItem.bottom - rcItem.top, ILC_COLORDDB | ILC_MASK, 1, 1); + + CClientDC dc(m_hWnd); + CDC dcMem; + dcMem.CreateCompatibleDC(dc); + ATLASSERT(dcMem.m_hDC != NULL); + dcMem.SetViewportOrg(-rcItem.left, -rcItem.top); + + CBitmap bmp; + bmp.CreateCompatibleBitmap(dc, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top); + ATLASSERT(bmp.m_hBitmap != NULL); + + HBITMAP hBmpOld = dcMem.SelectBitmap(bmp); +#ifndef _WIN32_WCE + m_tab.SendMessage(WM_PRINTCLIENT, (WPARAM)dcMem.m_hDC); +#else // CE specific + dcMem.Rectangle(&rcItem); +#endif // _WIN32_WCE + dcMem.SelectBitmap(hBmpOld); + + ATLVERIFY(m_ilDrag.Add(bmp.m_hBitmap, RGB(255, 0, 255)) != -1); + } + + void ShortenTitle(LPCTSTR lpstrTitle, LPTSTR lpstrShortTitle, int cchShortTitle) + { + if(lstrlen(lpstrTitle) >= cchShortTitle) + { + LPCTSTR lpstrEllipsis = _T("..."); + int cchEllipsis = lstrlen(lpstrEllipsis); + SecureHelper::strncpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle, cchShortTitle - cchEllipsis - 1); + SecureHelper::strcat_x(lpstrShortTitle, cchShortTitle, lpstrEllipsis); + } + else + { + SecureHelper::strcpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle); + } + } + +#ifndef _WIN32_WCE + void UpdateTooltipText(LPNMTTDISPINFO pTTDI) + { + ATLASSERT(pTTDI != NULL); + pTTDI->lpszText = (LPTSTR)GetPageTitle((int)pTTDI->hdr.idFrom); + } +#endif // !_WIN32_WCE + +// Text for menu items and title bar - override to provide different strings + static LPCTSTR GetEmptyListText() + { + return _T("(Empty)"); + } + + static LPCTSTR GetWindowsMenuItemText() + { + return _T("&Windows..."); + } + + static LPCTSTR GetTitleDividerText() + { + return _T(" - "); + } + +// Notifications - override to provide different behavior + void OnPageActivated(int nPage) + { + NMHDR nmhdr = { 0 }; + nmhdr.hwndFrom = m_hWnd; + nmhdr.idFrom = nPage; + nmhdr.code = TBVN_PAGEACTIVATED; + ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr); + } + + void OnContextMenu(int nPage, POINT pt) + { + m_tab.ClientToScreen(&pt); + + TBVCONTEXTMENUINFO cmi = { 0 }; + cmi.hdr.hwndFrom = m_hWnd; + cmi.hdr.idFrom = nPage; + cmi.hdr.code = TBVN_CONTEXTMENU; + cmi.pt = pt; + ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&cmi); + } +}; + + +class CTabView : public CTabViewImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_TabView"), 0, COLOR_APPWORKSPACE) +}; + +}; // namespace WTL + +#endif // __ATLCTRLX_H__ diff --git a/ext/CrashServer/external/WTL/Include/atlgdi.h b/ext/CrashServer/external/WTL/Include/atlgdi.h new file mode 100644 index 000000000..7ce868f35 --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atlgdi.h @@ -0,0 +1,3850 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLGDI_H__ +#define __ATLGDI_H__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLAPP_H__ + #error atlgdi.h requires atlapp.h to be included first +#endif + + +// protect template members from windowsx.h macros +#ifdef _INC_WINDOWSX + #undef CopyRgn + #undef CreateBrush + #undef CreatePen + #undef SelectBrush + #undef SelectPen + #undef SelectFont + #undef SelectBitmap +#endif // _INC_WINDOWSX + +// required libraries +#if !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE) + #pragma comment(lib, "msimg32.lib") +#endif // !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE) +#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + #pragma comment(lib, "opengl32.lib") +#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CPenT +// CBrushT +// CLogFont +// CFontT +// CBitmapT +// CPaletteT +// CRgnT +// CDCT +// CPaintDC +// CClientDC +// CWindowDC +// CMemoryDC +// CEnhMetaFileInfo +// CEnhMetaFileT +// CEnhMetaFileDC +// +// Global functions: +// AtlGetBitmapResourceInfo() +// AtlGetBitmapResourceBitsPerPixel() +// AtlIsAlphaBitmapResource() +// AtlIsDib16() +// AtlGetDibColorTableSize() +// AtlGetDibNumColors(), +// AtlGetDibBitmap() +// AtlCopyBitmap() +// AtlCreatePackedDib16() +// AtlSetClipboardDib16() +// AtlGetClipboardDib() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// Bitmap resource helpers to extract bitmap information for a bitmap resource + +inline LPBITMAPINFOHEADER AtlGetBitmapResourceInfo(HMODULE hModule, ATL::_U_STRINGorID image) +{ + HRSRC hResource = ::FindResource(hModule, image.m_lpstr, RT_BITMAP); + ATLASSERT(hResource != NULL); + HGLOBAL hGlobal = ::LoadResource(hModule, hResource); + ATLASSERT(hGlobal != NULL); + LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal); + ATLASSERT(pBitmapInfoHeader != NULL); + return pBitmapInfoHeader; +} + +inline WORD AtlGetBitmapResourceBitsPerPixel(HMODULE hModule, ATL::_U_STRINGorID image) +{ + LPBITMAPINFOHEADER pBitmapInfoHeader = AtlGetBitmapResourceInfo(hModule, image); + ATLASSERT(pBitmapInfoHeader != NULL); + return pBitmapInfoHeader->biBitCount; +} + +inline WORD AtlGetBitmapResourceBitsPerPixel(ATL::_U_STRINGorID image) +{ + return AtlGetBitmapResourceBitsPerPixel(ModuleHelper::GetResourceInstance(), image); +} + +/////////////////////////////////////////////////////////////////////////////// +// 32-bit (alpha channel) bitmap resource helper + +// Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6. +// If you want your app to work on older version of Windows, load non-alpha images if Common +// Controls version is less than 6. + +inline bool AtlIsAlphaBitmapResource(ATL::_U_STRINGorID image) +{ + return (AtlGetBitmapResourceBitsPerPixel(image) == 32); +} + + +/////////////////////////////////////////////////////////////////////////////// +// CPen + +template +class CPenT +{ +public: +// Data members + HPEN m_hPen; + +// Constructor/destructor/operators + CPenT(HPEN hPen = NULL) : m_hPen(hPen) + { } + + ~CPenT() + { + if(t_bManaged && m_hPen != NULL) + DeleteObject(); + } + + CPenT& operator =(HPEN hPen) + { + Attach(hPen); + return *this; + } + + void Attach(HPEN hPen) + { + if(t_bManaged && m_hPen != NULL && m_hPen != hPen) + ::DeleteObject(m_hPen); + m_hPen = hPen; + } + + HPEN Detach() + { + HPEN hPen = m_hPen; + m_hPen = NULL; + return hPen; + } + + operator HPEN() const { return m_hPen; } + + bool IsNull() const { return (m_hPen == NULL); } + +// Create methods + HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor) + { + ATLASSERT(m_hPen == NULL); + m_hPen = ::CreatePen(nPenStyle, nWidth, crColor); + return m_hPen; + } + +#ifndef _WIN32_WCE + HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL) + { + ATLASSERT(m_hPen == NULL); + m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle); + return m_hPen; + } +#endif // !_WIN32_WCE + + HPEN CreatePenIndirect(LPLOGPEN lpLogPen) + { + ATLASSERT(m_hPen == NULL); + m_hPen = ::CreatePenIndirect(lpLogPen); + return m_hPen; + } + + BOOL DeleteObject() + { + ATLASSERT(m_hPen != NULL); + BOOL bRet = ::DeleteObject(m_hPen); + if(bRet) + m_hPen = NULL; + return bRet; + } + +// Attributes + int GetLogPen(LOGPEN* pLogPen) const + { + ATLASSERT(m_hPen != NULL); + return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen); + } + + bool GetLogPen(LOGPEN& LogPen) const + { + ATLASSERT(m_hPen != NULL); + return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN)); + } + +#ifndef _WIN32_WCE + int GetExtLogPen(EXTLOGPEN* pLogPen) const + { + ATLASSERT(m_hPen != NULL); + return ::GetObject(m_hPen, sizeof(EXTLOGPEN), pLogPen); + } + + bool GetExtLogPen(EXTLOGPEN& ExtLogPen) const + { + ATLASSERT(m_hPen != NULL); + return (::GetObject(m_hPen, sizeof(EXTLOGPEN), &ExtLogPen) == sizeof(EXTLOGPEN)); + } +#endif // !_WIN32_WCE +}; + +typedef CPenT CPenHandle; +typedef CPenT CPen; + + +/////////////////////////////////////////////////////////////////////////////// +// CBrush + +template +class CBrushT +{ +public: +// Data members + HBRUSH m_hBrush; + +// Constructor/destructor/operators + CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush) + { } + + ~CBrushT() + { + if(t_bManaged && m_hBrush != NULL) + DeleteObject(); + } + + CBrushT& operator =(HBRUSH hBrush) + { + Attach(hBrush); + return *this; + } + + void Attach(HBRUSH hBrush) + { + if(t_bManaged && m_hBrush != NULL && m_hBrush != hBrush) + ::DeleteObject(m_hBrush); + m_hBrush = hBrush; + } + + HBRUSH Detach() + { + HBRUSH hBrush = m_hBrush; + m_hBrush = NULL; + return hBrush; + } + + operator HBRUSH() const { return m_hBrush; } + + bool IsNull() const { return (m_hBrush == NULL); } + +// Create methods + HBRUSH CreateSolidBrush(COLORREF crColor) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreateSolidBrush(crColor); + return m_hBrush; + } + +#ifndef _WIN32_WCE + HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreateHatchBrush(nIndex, crColor); + return m_hBrush; + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush) + { + ATLASSERT(m_hBrush == NULL); +#ifndef _WIN32_WCE + m_hBrush = ::CreateBrushIndirect(lpLogBrush); +#else // CE specific + m_hBrush = ATL::CreateBrushIndirect(lpLogBrush); +#endif // _WIN32_WCE + return m_hBrush; + } +#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + + HBRUSH CreatePatternBrush(HBITMAP hBitmap) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreatePatternBrush(hBitmap); + return m_hBrush; + } + + HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage) + { + ATLASSERT(hPackedDIB != NULL); + const void* lpPackedDIB = GlobalLock(hPackedDIB); + ATLASSERT(lpPackedDIB != NULL); + m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage); + GlobalUnlock(hPackedDIB); + return m_hBrush; + } + + HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage); + return m_hBrush; + } + + HBRUSH CreateSysColorBrush(int nIndex) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::GetSysColorBrush(nIndex); + return m_hBrush; + } + + BOOL DeleteObject() + { + ATLASSERT(m_hBrush != NULL); + BOOL bRet = ::DeleteObject(m_hBrush); + if(bRet) + m_hBrush = NULL; + return bRet; + } + +// Attributes + int GetLogBrush(LOGBRUSH* pLogBrush) const + { + ATLASSERT(m_hBrush != NULL); + return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush); + } + + bool GetLogBrush(LOGBRUSH& LogBrush) const + { + ATLASSERT(m_hBrush != NULL); + return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH)); + } +}; + +typedef CBrushT CBrushHandle; +typedef CBrushT CBrush; + + +/////////////////////////////////////////////////////////////////////////////// +// CFont + +class CLogFont : public LOGFONT +{ +public: + CLogFont() + { + memset(this, 0, sizeof(LOGFONT)); + } + + CLogFont(const LOGFONT& lf) + { + Copy(&lf); + } + + CLogFont(HFONT hFont) + { + ATLASSERT(::GetObjectType(hFont) == OBJ_FONT); + ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this); + } + + HFONT CreateFontIndirect() + { + return ::CreateFontIndirect(this); + } + + void SetBold() + { + lfWeight = FW_BOLD; + } + + bool IsBold() const + { + return (lfWeight >= FW_BOLD); + } + + void MakeBolder(int iScale = 1) + { + lfWeight += FW_BOLD * iScale; + } + + void MakeLarger(int iScale) + { + if(lfHeight > 0) + lfHeight += iScale; + else + lfHeight -= iScale; + } + + void SetHeight(LONG nPointSize, HDC hDC = NULL) + { + // For MM_TEXT mapping mode + lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC, LOGPIXELSY), 72); + } + + LONG GetHeight(HDC hDC = NULL) const + { + // For MM_TEXT mapping mode + return ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC, LOGPIXELSY)); + } + + LONG GetDeciPointHeight(HDC hDC = NULL) const + { +#ifndef _WIN32_WCE + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC, &ptOrg, 1); + POINT pt = { 0, 0 }; + pt.y = abs(lfHeight) + ptOrg.y; + ::LPtoDP(hDC,&pt,1); + return ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point +#else // CE specific + // DP and LP are always the same on CE + return ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point +#endif // _WIN32_WCE + } + + void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL) + { +#ifndef _WIN32_WCE + POINT pt = { 0, 0 }; + pt.y = ::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point + ::DPtoLP(hDC, &pt, 1); + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC, &ptOrg, 1); + lfHeight = -abs(pt.y - ptOrg.y); +#else // CE specific + // DP and LP are always the same on CE + lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point +#endif // _WIN32_WCE + } + +#ifndef _WIN32_WCE + void SetCaptionFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfCaptionFont); + } + + void SetMenuFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfMenuFont); + } + + void SetStatusFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfStatusFont); + } + + void SetMessageBoxFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfMessageFont); + } +#endif // !_WIN32_WCE + + void Copy(const LOGFONT* pLogFont) + { + ATLASSERT(pLogFont != NULL); + *(LOGFONT*)this = *pLogFont; + } + + CLogFont& operator =(const CLogFont& src) + { + Copy(&src); + return *this; + } + + CLogFont& operator =(const LOGFONT& src) + { + Copy(&src); + return *this; + } + + CLogFont& operator =(HFONT hFont) + { + ATLASSERT(::GetObjectType(hFont) == OBJ_FONT); + ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this); + return *this; + } + + bool operator ==(const LOGFONT& logfont) const + { + return(logfont.lfHeight == lfHeight && + logfont.lfWidth == lfWidth && + logfont.lfEscapement == lfEscapement && + logfont.lfOrientation == lfOrientation && + logfont.lfWeight == lfWeight && + logfont.lfItalic == lfItalic && + logfont.lfUnderline == lfUnderline && + logfont.lfStrikeOut == lfStrikeOut && + logfont.lfCharSet == lfCharSet && + logfont.lfOutPrecision == lfOutPrecision && + logfont.lfClipPrecision == lfClipPrecision && + logfont.lfQuality == lfQuality && + logfont.lfPitchAndFamily == lfPitchAndFamily && + lstrcmp(logfont.lfFaceName, lfFaceName) == 0); + } +}; + + +template +class CFontT +{ +public: +// Data members + HFONT m_hFont; + +// Constructor/destructor/operators + CFontT(HFONT hFont = NULL) : m_hFont(hFont) + { } + + ~CFontT() + { + if(t_bManaged && m_hFont != NULL) + DeleteObject(); + } + + CFontT& operator =(HFONT hFont) + { + Attach(hFont); + return *this; + } + + void Attach(HFONT hFont) + { + if(t_bManaged && m_hFont != NULL && m_hFont != hFont) + ::DeleteObject(m_hFont); + m_hFont = hFont; + } + + HFONT Detach() + { + HFONT hFont = m_hFont; + m_hFont = NULL; + return hFont; + } + + operator HFONT() const { return m_hFont; } + + bool IsNull() const { return (m_hFont == NULL); } + +// Create methods + HFONT CreateFontIndirect(const LOGFONT* lpLogFont) + { + ATLASSERT(m_hFont == NULL); + m_hFont = ::CreateFontIndirect(lpLogFont); + return m_hFont; + } + +#if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500) + HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex) + { + ATLASSERT(m_hFont == NULL); + m_hFont = ::CreateFontIndirectEx(penumlfex); + return m_hFont; + } +#endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500) + +#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + HFONT CreateFont(int nHeight, int nWidth, int nEscapement, + int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, + BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, + BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, + LPCTSTR lpszFacename) + { + ATLASSERT(m_hFont == NULL); +#ifndef _WIN32_WCE + m_hFont = ::CreateFont(nHeight, nWidth, nEscapement, + nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, + nCharSet, nOutPrecision, nClipPrecision, nQuality, + nPitchAndFamily, lpszFacename); +#else // CE specific + m_hFont = ATL::CreateFont(nHeight, nWidth, nEscapement, + nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, + nCharSet, nOutPrecision, nClipPrecision, nQuality, + nPitchAndFamily, lpszFacename); +#endif // _WIN32_WCE + return m_hFont; + } +#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + + HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL, bool bBold = false, bool bItalic = false) + { + LOGFONT logFont = { 0 }; + logFont.lfCharSet = DEFAULT_CHARSET; + logFont.lfHeight = nPointSize; + SecureHelper::strncpy_x(logFont.lfFaceName, _countof(logFont.lfFaceName), lpszFaceName, _TRUNCATE); + + if(bBold) + logFont.lfWeight = FW_BOLD; + if(bItalic) + logFont.lfItalic = (BYTE)TRUE; + + return CreatePointFontIndirect(&logFont, hDC); + } + + HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL) + { + HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); + + // convert nPointSize to logical units based on hDC + LOGFONT logFont = *lpLogFont; +#ifndef _WIN32_WCE + POINT pt = { 0, 0 }; + pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point + ::DPtoLP(hDC1, &pt, 1); + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC1, &ptOrg, 1); + logFont.lfHeight = -abs(pt.y - ptOrg.y); +#else // CE specific + // DP and LP are always the same on CE + logFont.lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720)); // 72 points/inch, 10 decipoints/point +#endif // _WIN32_WCE + + if(hDC == NULL) + ::ReleaseDC(NULL, hDC1); + + return CreateFontIndirect(&logFont); + } + + BOOL DeleteObject() + { + ATLASSERT(m_hFont != NULL); + BOOL bRet = ::DeleteObject(m_hFont); + if(bRet) + m_hFont = NULL; + return bRet; + } + +// Attributes + int GetLogFont(LOGFONT* pLogFont) const + { + ATLASSERT(m_hFont != NULL); + return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont); + } + + bool GetLogFont(LOGFONT& LogFont) const + { + ATLASSERT(m_hFont != NULL); + return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT)); + } +}; + +typedef CFontT CFontHandle; +typedef CFontT CFont; + + +/////////////////////////////////////////////////////////////////////////////// +// CBitmap + +template +class CBitmapT +{ +public: +// Data members + HBITMAP m_hBitmap; + +// Constructor/destructor/operators + CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap) + { } + + ~CBitmapT() + { + if(t_bManaged && m_hBitmap != NULL) + DeleteObject(); + } + + CBitmapT& operator =(HBITMAP hBitmap) + { + Attach(hBitmap); + return *this; + } + + void Attach(HBITMAP hBitmap) + { + if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap) + ::DeleteObject(m_hBitmap); + m_hBitmap = hBitmap; + } + + HBITMAP Detach() + { + HBITMAP hBitmap = m_hBitmap; + m_hBitmap = NULL; + return hBitmap; + } + + operator HBITMAP() const { return m_hBitmap; } + + bool IsNull() const { return (m_hBitmap == NULL); } + +// Create and load methods + HBITMAP LoadBitmap(ATL::_U_STRINGorID bitmap) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr); + return m_hBitmap; + } + + HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_ + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap)); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateMappedBitmap(ModuleHelper::GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateBitmapIndirect(lpBitmap); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + BOOL DeleteObject() + { + ATLASSERT(m_hBitmap != NULL); + BOOL bRet = ::DeleteObject(m_hBitmap); + if(bRet) + m_hBitmap = NULL; + return bRet; + } + +// Attributes + int GetBitmap(BITMAP* pBitMap) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap); + } + + bool GetBitmap(BITMAP& bm) const + { + ATLASSERT(m_hBitmap != NULL); + return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP)); + } + + bool GetSize(SIZE& size) const + { + ATLASSERT(m_hBitmap != NULL); + BITMAP bm = { 0 }; + if(!GetBitmap(&bm)) + return false; + size.cx = bm.bmWidth; + size.cy = bm.bmHeight; + return true; + } + +#ifndef _WIN32_WCE + DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetBitmapBits(m_hBitmap, dwCount, lpBits); + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + DWORD SetBitmapBits(DWORD dwCount, const void* lpBits) + { + ATLASSERT(m_hBitmap != NULL); + return ::SetBitmapBits(m_hBitmap, dwCount, lpBits); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + +#ifndef _WIN32_WCE + BOOL GetBitmapDimension(LPSIZE lpSize) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetBitmapDimensionEx(m_hBitmap, lpSize); + } + + BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hBitmap != NULL); + return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize); + } + +// DIB support + HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); + } + + int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) + { + ATLASSERT(m_hBitmap != NULL); + return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); + } +#endif // !_WIN32_WCE +}; + +typedef CBitmapT CBitmapHandle; +typedef CBitmapT CBitmap; + + +/////////////////////////////////////////////////////////////////////////////// +// CPalette + +template +class CPaletteT +{ +public: +// Data members + HPALETTE m_hPalette; + +// Constructor/destructor/operators + CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette) + { } + + ~CPaletteT() + { + if(t_bManaged && m_hPalette != NULL) + DeleteObject(); + } + + CPaletteT& operator =(HPALETTE hPalette) + { + Attach(hPalette); + return *this; + } + + void Attach(HPALETTE hPalette) + { + if(t_bManaged && m_hPalette != NULL && m_hPalette != hPalette) + ::DeleteObject(m_hPalette); + m_hPalette = hPalette; + } + + HPALETTE Detach() + { + HPALETTE hPalette = m_hPalette; + m_hPalette = NULL; + return hPalette; + } + + operator HPALETTE() const { return m_hPalette; } + + bool IsNull() const { return (m_hPalette == NULL); } + +// Create methods + HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette) + { + ATLASSERT(m_hPalette == NULL); + m_hPalette = ::CreatePalette(lpLogPalette); + return m_hPalette; + } + +#ifndef _WIN32_WCE + HPALETTE CreateHalftonePalette(HDC hDC) + { + ATLASSERT(m_hPalette == NULL); + ATLASSERT(hDC != NULL); + m_hPalette = ::CreateHalftonePalette(hDC); + return m_hPalette; + } +#endif // !_WIN32_WCE + + BOOL DeleteObject() + { + ATLASSERT(m_hPalette != NULL); + BOOL bRet = ::DeleteObject(m_hPalette); + if(bRet) + m_hPalette = NULL; + return bRet; + } + +// Attributes + int GetEntryCount() const + { + ATLASSERT(m_hPalette != NULL); + WORD nEntries = 0; + ::GetObject(m_hPalette, sizeof(WORD), &nEntries); + return (int)nEntries; + } + + UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const + { + ATLASSERT(m_hPalette != NULL); + return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); + } + + UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) + { + ATLASSERT(m_hPalette != NULL); + return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); + } + +// Operations +#ifndef _WIN32_WCE + void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) + { + ATLASSERT(m_hPalette != NULL); + ::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); + } + + BOOL ResizePalette(UINT nNumEntries) + { + ATLASSERT(m_hPalette != NULL); + return ::ResizePalette(m_hPalette, nNumEntries); + } +#endif // !_WIN32_WCE + + UINT GetNearestPaletteIndex(COLORREF crColor) const + { + ATLASSERT(m_hPalette != NULL); + return ::GetNearestPaletteIndex(m_hPalette, crColor); + } +}; + +typedef CPaletteT CPaletteHandle; +typedef CPaletteT CPalette; + + +/////////////////////////////////////////////////////////////////////////////// +// CRgn + +template +class CRgnT +{ +public: +// Data members + HRGN m_hRgn; + +// Constructor/destructor/operators + CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn) + { } + + ~CRgnT() + { + if(t_bManaged && m_hRgn != NULL) + DeleteObject(); + } + + CRgnT& operator =(HRGN hRgn) + { + Attach(hRgn); + return *this; + } + + void Attach(HRGN hRgn) + { + if(t_bManaged && m_hRgn != NULL && m_hRgn != hRgn) + ::DeleteObject(m_hRgn); + m_hRgn = hRgn; + } + + HRGN Detach() + { + HRGN hRgn = m_hRgn; + m_hRgn = NULL; + return hRgn; + } + + operator HRGN() const { return m_hRgn; } + + bool IsNull() const { return (m_hRgn == NULL); } + +// Create methods + HRGN CreateRectRgn(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateRectRgn(x1, y1, x2, y2); + return m_hRgn; + } + + HRGN CreateRectRgnIndirect(LPCRECT lpRect) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateRectRgnIndirect(lpRect); + return m_hRgn; + } + +#ifndef _WIN32_WCE + HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2); + return m_hRgn; + } + + HRGN CreateEllipticRgnIndirect(LPCRECT lpRect) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateEllipticRgnIndirect(lpRect); + return m_hRgn; + } + + HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode); + return m_hRgn; + } + + HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode); + return m_hRgn; + } + + HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3); + return m_hRgn; + } + + HRGN CreateFromPath(HDC hDC) + { + ATLASSERT(m_hRgn == NULL); + ATLASSERT(hDC != NULL); + m_hRgn = ::PathToRegion(hDC); + return m_hRgn; + } + + HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData); + return m_hRgn; + } +#endif // !_WIN32_WCE + + BOOL DeleteObject() + { + ATLASSERT(m_hRgn != NULL); + BOOL bRet = ::DeleteObject(m_hRgn); + if(bRet) + m_hRgn = NULL; + return bRet; + } + +// Operations + void SetRectRgn(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hRgn != NULL); + ::SetRectRgn(m_hRgn, x1, y1, x2, y2); + } + + void SetRectRgn(LPCRECT lpRect) + { + ATLASSERT(m_hRgn != NULL); + ::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + + int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode) + { + ATLASSERT(m_hRgn != NULL); + return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode); + } + + int CombineRgn(HRGN hRgnSrc, int nCombineMode) + { + ATLASSERT(m_hRgn != NULL); + return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode); + } + + int CopyRgn(HRGN hRgnSrc) + { + ATLASSERT(m_hRgn != NULL); + return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY); + } + + BOOL EqualRgn(HRGN hRgn) const + { + ATLASSERT(m_hRgn != NULL); + return ::EqualRgn(m_hRgn, hRgn); + } + + int OffsetRgn(int x, int y) + { + ATLASSERT(m_hRgn != NULL); + return ::OffsetRgn(m_hRgn, x, y); + } + + int OffsetRgn(POINT point) + { + ATLASSERT(m_hRgn != NULL); + return ::OffsetRgn(m_hRgn, point.x, point.y); + } + + int GetRgnBox(LPRECT lpRect) const + { + ATLASSERT(m_hRgn != NULL); + return ::GetRgnBox(m_hRgn, lpRect); + } + + BOOL PtInRegion(int x, int y) const + { + ATLASSERT(m_hRgn != NULL); + return ::PtInRegion(m_hRgn, x, y); + } + + BOOL PtInRegion(POINT point) const + { + ATLASSERT(m_hRgn != NULL); + return ::PtInRegion(m_hRgn, point.x, point.y); + } + + BOOL RectInRegion(LPCRECT lpRect) const + { + ATLASSERT(m_hRgn != NULL); + return ::RectInRegion(m_hRgn, lpRect); + } + + int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const + { + ATLASSERT(m_hRgn != NULL); + return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData); + } +}; + +typedef CRgnT CRgnHandle; +typedef CRgnT CRgn; + + +/////////////////////////////////////////////////////////////////////////////// +// CDC - The device context class + +template +class CDCT +{ +public: +// Data members + HDC m_hDC; + +// Constructor/destructor/operators + CDCT(HDC hDC = NULL) : m_hDC(hDC) + { + } + + ~CDCT() + { + if(t_bManaged && m_hDC != NULL) + ::DeleteDC(Detach()); + } + + CDCT& operator =(HDC hDC) + { + Attach(hDC); + return *this; + } + + void Attach(HDC hDC) + { + if(t_bManaged && m_hDC != NULL && m_hDC != hDC) + ::DeleteDC(m_hDC); + m_hDC = hDC; + } + + HDC Detach() + { + HDC hDC = m_hDC; + m_hDC = NULL; + return hDC; + } + + operator HDC() const { return m_hDC; } + + bool IsNull() const { return (m_hDC == NULL); } + +// Operations +#ifndef _WIN32_WCE + HWND WindowFromDC() const + { + ATLASSERT(m_hDC != NULL); + return ::WindowFromDC(m_hDC); + } +#endif // !_WIN32_WCE + + CPenHandle GetCurrentPen() const + { + ATLASSERT(m_hDC != NULL); + return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN)); + } + + CBrushHandle GetCurrentBrush() const + { + ATLASSERT(m_hDC != NULL); + return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH)); + } + + CPaletteHandle GetCurrentPalette() const + { + ATLASSERT(m_hDC != NULL); + return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL)); + } + + CFontHandle GetCurrentFont() const + { + ATLASSERT(m_hDC != NULL); + return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT)); + } + + CBitmapHandle GetCurrentBitmap() const + { + ATLASSERT(m_hDC != NULL); + return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP)); + } + + HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData) + { + ATLASSERT(m_hDC == NULL); + m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData); + return m_hDC; + } + + HDC CreateCompatibleDC(HDC hDC = NULL) + { + ATLASSERT(m_hDC == NULL); + m_hDC = ::CreateCompatibleDC(hDC); + return m_hDC; + } + + BOOL DeleteDC() + { + if(m_hDC == NULL) + return FALSE; + BOOL bRet = ::DeleteDC(m_hDC); + if(bRet) + m_hDC = NULL; + return bRet; + } + +// Device-Context Functions + int SaveDC() + { + ATLASSERT(m_hDC != NULL); + return ::SaveDC(m_hDC); + } + + BOOL RestoreDC(int nSavedDC) + { + ATLASSERT(m_hDC != NULL); + return ::RestoreDC(m_hDC, nSavedDC); + } + + int GetDeviceCaps(int nIndex) const + { + ATLASSERT(m_hDC != NULL); + return ::GetDeviceCaps(m_hDC, nIndex); + } + +#ifndef _WIN32_WCE + UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags) + { + ATLASSERT(m_hDC != NULL); + return ::SetBoundsRect(m_hDC, lpRectBounds, flags); + } + + UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const + { + ATLASSERT(m_hDC != NULL); + return ::GetBoundsRect(m_hDC, lpRectBounds, flags); + } + + BOOL ResetDC(const DEVMODE* lpDevMode) + { + ATLASSERT(m_hDC != NULL); + return ::ResetDC(m_hDC, lpDevMode) != NULL; + } + +// Drawing-Tool Functions + BOOL GetBrushOrg(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetBrushOrgEx(m_hDC, lpPoint); + } +#endif // !_WIN32_WCE + + BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetBrushOrgEx(m_hDC, x, y, lpPoint); + } + + BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet); + } + +#ifndef _WIN32_WCE + int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData) + { + ATLASSERT(m_hDC != NULL); +#ifdef STRICT + return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData); +#else + return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData); +#endif + } +#endif // !_WIN32_WCE + +// Type-safe selection helpers + HPEN SelectPen(HPEN hPen) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN); +#else // CE specific + ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN); +#endif // _WIN32_WCE + return (HPEN)::SelectObject(m_hDC, hPen); + } + + HBRUSH SelectBrush(HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH); + return (HBRUSH)::SelectObject(m_hDC, hBrush); + } + + HFONT SelectFont(HFONT hFont) + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT); + return (HFONT)::SelectObject(m_hDC, hFont); + } + + HBITMAP SelectBitmap(HBITMAP hBitmap) + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP); + return (HBITMAP)::SelectObject(m_hDC, hBitmap); + } + + int SelectRgn(HRGN hRgn) // special return for regions + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION); + return PtrToInt(::SelectObject(m_hDC, hRgn)); + } + +// Type-safe selection helpers for stock objects + HPEN SelectStockPen(int nPen) + { + ATLASSERT(m_hDC != NULL); +#if (_WIN32_WINNT >= 0x0500) + ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN); +#else + ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN); +#endif // !(_WIN32_WINNT >= 0x0500) + return SelectPen((HPEN)::GetStockObject(nPen)); + } + + HBRUSH SelectStockBrush(int nBrush) + { +#if (_WIN32_WINNT >= 0x0500) + ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH); +#else + ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH); +#endif // !(_WIN32_WINNT >= 0x0500) + return SelectBrush((HBRUSH)::GetStockObject(nBrush)); + } + + HFONT SelectStockFont(int nFont) + { +#ifndef _WIN32_WCE + ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT); +#else // CE specific + ATLASSERT(nFont == SYSTEM_FONT); +#endif // _WIN32_WCE + return SelectFont((HFONT)::GetStockObject(nFont)); + } + + HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground) + { + ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported + return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground); + } + +// Color and Color Palette Functions + COLORREF GetNearestColor(COLORREF crColor) const + { + ATLASSERT(m_hDC != NULL); + return ::GetNearestColor(m_hDC, crColor); + } + + HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground) + { + ATLASSERT(m_hDC != NULL); + + return ::SelectPalette(m_hDC, hPalette, bForceBackground); + } + + UINT RealizePalette() + { + ATLASSERT(m_hDC != NULL); + return ::RealizePalette(m_hDC); + } + +#ifndef _WIN32_WCE + void UpdateColors() + { + ATLASSERT(m_hDC != NULL); + ::UpdateColors(m_hDC); + } +#endif // !_WIN32_WCE + +// Drawing-Attribute Functions + COLORREF GetBkColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetBkColor(m_hDC); + } + + int GetBkMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetBkMode(m_hDC); + } + +#ifndef _WIN32_WCE + int GetPolyFillMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetPolyFillMode(m_hDC); + } + + int GetROP2() const + { + ATLASSERT(m_hDC != NULL); + return ::GetROP2(m_hDC); + } + + int GetStretchBltMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetStretchBltMode(m_hDC); + } +#endif // !_WIN32_WCE + + COLORREF GetTextColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextColor(m_hDC); + } + + COLORREF SetBkColor(COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetBkColor(m_hDC, crColor); + } + + int SetBkMode(int nBkMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetBkMode(m_hDC, nBkMode); + } + +#ifndef _WIN32_WCE + int SetPolyFillMode(int nPolyFillMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetPolyFillMode(m_hDC, nPolyFillMode); + } +#endif // !_WIN32_WCE + + int SetROP2(int nDrawMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetROP2(m_hDC, nDrawMode); + } + +#ifndef _WIN32_WCE + int SetStretchBltMode(int nStretchMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetStretchBltMode(m_hDC, nStretchMode); + } +#endif // !_WIN32_WCE + + COLORREF SetTextColor(COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextColor(m_hDC, crColor); + } + +#ifndef _WIN32_WCE + BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const + { + ATLASSERT(m_hDC != NULL); + return ::GetColorAdjustment(m_hDC, lpColorAdjust); + } + + BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust) + { + ATLASSERT(m_hDC != NULL); + return ::SetColorAdjustment(m_hDC, lpColorAdjust); + } + +// Mapping Functions + int GetMapMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetMapMode(m_hDC); + } + + BOOL GetViewportOrg(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetViewportOrgEx(m_hDC, lpPoint); + } + + int SetMapMode(int nMapMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetMapMode(m_hDC, nMapMode); + } +#endif // !_WIN32_WCE + + // Viewport Origin + BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetViewportOrgEx(m_hDC, x, y, lpPoint); + } + + BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetViewportOrg(point.x, point.y, lpPointRet); + } + +#ifndef _WIN32_WCE + BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint); + } + + // Viewport Extent + BOOL GetViewportExt(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetViewportExtEx(m_hDC, lpSize); + } + + BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetViewportExtEx(m_hDC, x, y, lpSize); + } + + BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetViewportExt(size.cx, size.cy, lpSizeRet); + } + + BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize); + } +#endif // !_WIN32_WCE + + // Window Origin +#ifndef _WIN32_WCE + BOOL GetWindowOrg(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetWindowOrgEx(m_hDC, lpPoint); + } + + BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetWindowOrgEx(m_hDC, x, y, lpPoint); + } + + BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetWindowOrg(point.x, point.y, lpPointRet); + } + + BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint); + } + + // Window extent + BOOL GetWindowExt(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetWindowExtEx(m_hDC, lpSize); + } + + BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetWindowExtEx(m_hDC, x, y, lpSize); + } + + BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetWindowExt(size.cx, size.cy, lpSizeRet); + } + + BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize); + } + +// Coordinate Functions + BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const + { + ATLASSERT(m_hDC != NULL); + return ::DPtoLP(m_hDC, lpPoints, nCount); + } + + BOOL DPtoLP(LPRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2); + } + + BOOL DPtoLP(LPSIZE lpSize) const + { + SIZE sizeWinExt = { 0, 0 }; + if(!GetWindowExt(&sizeWinExt)) + return FALSE; + SIZE sizeVpExt = { 0, 0 }; + if(!GetViewportExt(&sizeVpExt)) + return FALSE; + lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx)); + lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy)); + return TRUE; + } + + BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const + { + ATLASSERT(m_hDC != NULL); + return ::LPtoDP(m_hDC, lpPoints, nCount); + } + + BOOL LPtoDP(LPRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2); + } + + BOOL LPtoDP(LPSIZE lpSize) const + { + SIZE sizeWinExt = { 0, 0 }; + if(!GetWindowExt(&sizeWinExt)) + return FALSE; + SIZE sizeVpExt = { 0, 0 }; + if(!GetViewportExt(&sizeVpExt)) + return FALSE; + lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx)); + lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy)); + return TRUE; + } + +// Special Coordinate Functions (useful for dealing with metafiles and OLE) + #define HIMETRIC_INCH 2540 // HIMETRIC units per inch + + void DPtoHIMETRIC(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + int nMapMode; + if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT) + { + // when using a constrained map mode, map against physical inch + ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC); + DPtoLP(lpSize); + ((CDCHandle*)this)->SetMapMode(nMapMode); + } + else + { + // map against logical inch for non-constrained mapping modes + int cxPerInch = GetDeviceCaps(LOGPIXELSX); + int cyPerInch = GetDeviceCaps(LOGPIXELSY); + ATLASSERT(cxPerInch != 0 && cyPerInch != 0); + lpSize->cx = ::MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch); + lpSize->cy = ::MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch); + } + } + + void HIMETRICtoDP(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + int nMapMode; + if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT) + { + // when using a constrained map mode, map against physical inch + ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC); + LPtoDP(lpSize); + ((CDCHandle*)this)->SetMapMode(nMapMode); + } + else + { + // map against logical inch for non-constrained mapping modes + int cxPerInch = GetDeviceCaps(LOGPIXELSX); + int cyPerInch = GetDeviceCaps(LOGPIXELSY); + ATLASSERT(cxPerInch != 0 && cyPerInch != 0); + lpSize->cx = ::MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH); + lpSize->cy = ::MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH); + } + } + + void LPtoHIMETRIC(LPSIZE lpSize) const + { + LPtoDP(lpSize); + DPtoHIMETRIC(lpSize); + } + + void HIMETRICtoLP(LPSIZE lpSize) const + { + HIMETRICtoDP(lpSize); + DPtoLP(lpSize); + } +#endif // !_WIN32_WCE + +// Region Functions + BOOL FillRgn(HRGN hRgn, HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + return ::FillRgn(m_hDC, hRgn, hBrush); + } + +#ifndef _WIN32_WCE + BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight) + { + ATLASSERT(m_hDC != NULL); + return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight); + } + + BOOL InvertRgn(HRGN hRgn) + { + ATLASSERT(m_hDC != NULL); + return ::InvertRgn(m_hDC, hRgn); + } + + BOOL PaintRgn(HRGN hRgn) + { + ATLASSERT(m_hDC != NULL); + return ::PaintRgn(m_hDC, hRgn); + } +#endif // !_WIN32_WCE + +// Clipping Functions + int GetClipBox(LPRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::GetClipBox(m_hDC, lpRect); + } + + int GetClipRgn(CRgn& region) const + { + ATLASSERT(m_hDC != NULL); + if(region.IsNull()) + region.CreateRectRgn(0, 0, 0, 0); + + int nRet = ::GetClipRgn(m_hDC, region); + if(nRet != 1) + region.DeleteObject(); + + return nRet; + } + +#ifndef _WIN32_WCE + BOOL PtVisible(int x, int y) const + { + ATLASSERT(m_hDC != NULL); + return ::PtVisible(m_hDC, x, y); + } + + BOOL PtVisible(POINT point) const + { + ATLASSERT(m_hDC != NULL); + return ::PtVisible(m_hDC, point.x, point.y); + } +#endif // !_WIN32_WCE + + BOOL RectVisible(LPCRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::RectVisible(m_hDC, lpRect); + } + + int SelectClipRgn(HRGN hRgn) + { + ATLASSERT(m_hDC != NULL); + return ::SelectClipRgn(m_hDC, (HRGN)hRgn); + } + + int ExcludeClipRect(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2); + } + + int ExcludeClipRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + +#ifndef _WIN32_WCE + int ExcludeUpdateRgn(HWND hWnd) + { + ATLASSERT(m_hDC != NULL); + return ::ExcludeUpdateRgn(m_hDC, hWnd); + } +#endif // !_WIN32_WCE + + int IntersectClipRect(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::IntersectClipRect(m_hDC, x1, y1, x2, y2); + } + + int IntersectClipRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + +#ifndef _WIN32_WCE + int OffsetClipRgn(int x, int y) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetClipRgn(m_hDC, x, y); + } + + int OffsetClipRgn(SIZE size) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetClipRgn(m_hDC, size.cx, size.cy); + } + + int SelectClipRgn(HRGN hRgn, int nMode) + { + ATLASSERT(m_hDC != NULL); + return ::ExtSelectClipRgn(m_hDC, hRgn, nMode); + } +#endif // !_WIN32_WCE + +// Line-Output Functions +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + BOOL GetCurrentPosition(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCurrentPositionEx(m_hDC, lpPoint); + } + + BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::MoveToEx(m_hDC, x, y, lpPoint); + } + + BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return MoveTo(point.x, point.y, lpPointRet); + } + + BOOL LineTo(int x, int y) + { + ATLASSERT(m_hDC != NULL); + return ::LineTo(m_hDC, x, y); + } + + BOOL LineTo(POINT point) + { + ATLASSERT(m_hDC != NULL); + return LineTo(point.x, point.y); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + +#ifndef _WIN32_WCE + BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ::Arc(m_hDC, lpRect->left, lpRect->top, + lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, + ptEnd.x, ptEnd.y); + } +#endif // !_WIN32_WCE + + BOOL Polyline(LPPOINT lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::Polyline(m_hDC, lpPoints, nCount); + } + +#ifndef _WIN32_WCE + BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) + { + ATLASSERT(m_hDC != NULL); + return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle); + } + + BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ArcTo(lpRect->left, lpRect->top, lpRect->right, + lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); + } + + int GetArcDirection() const + { + ATLASSERT(m_hDC != NULL); + return ::GetArcDirection(m_hDC); + } + + int SetArcDirection(int nArcDirection) + { + ATLASSERT(m_hDC != NULL); + return ::SetArcDirection(m_hDC, nArcDirection); + } + + BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount); + } + + BOOL PolylineTo(const POINT* lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolylineTo(m_hDC, lpPoints, nCount); + } + + BOOL PolyPolyline(const POINT* lpPoints, + const DWORD* lpPolyPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount); + } + + BOOL PolyBezier(const POINT* lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyBezier(m_hDC, lpPoints, nCount); + } + + BOOL PolyBezierTo(const POINT* lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyBezierTo(m_hDC, lpPoints, nCount); + } +#endif // !_WIN32_WCE + +// Simple Drawing Functions + BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + return ::FillRect(m_hDC, lpRect, hBrush); + } + + BOOL FillRect(LPCRECT lpRect, int nColorIndex) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + return ::FillRect(m_hDC, lpRect, (HBRUSH)LongToPtr(nColorIndex + 1)); +#else // CE specific + return ::FillRect(m_hDC, lpRect, ::GetSysColorBrush(nColorIndex)); +#endif // _WIN32_WCE + } + +#ifndef _WIN32_WCE + BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + return ::FrameRect(m_hDC, lpRect, hBrush); + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + BOOL InvertRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::InvertRect(m_hDC, lpRect); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + + BOOL DrawIcon(int x, int y, HICON hIcon) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(m_hDC, x, y, hIcon); +#else // CE specific + return ::DrawIconEx(m_hDC, x, y, hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIcon(POINT point, HICON hIcon) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(m_hDC, point.x, point.y, hIcon); +#else // CE specific + return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + + BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + +#ifndef _WIN32_WCE + BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP); + } + + BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON); + } + + BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT)); + } + + BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX); + } +#endif // !_WIN32_WCE + +// Ellipse and Polygon Functions +#ifndef _WIN32_WCE + BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); + } +#endif // !_WIN32_WCE + + void DrawFocusRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + ::DrawFocusRect(m_hDC, lpRect); + } + + BOOL Ellipse(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::Ellipse(m_hDC, x1, y1, x2, y2); + } + + BOOL Ellipse(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + +#ifndef _WIN32_WCE + BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); + } +#endif // !_WIN32_WCE + + BOOL Polygon(LPPOINT lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::Polygon(m_hDC, lpPoints, nCount); + } + +#ifndef _WIN32_WCE + BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount); + } +#endif // !_WIN32_WCE + + BOOL Rectangle(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::Rectangle(m_hDC, x1, y1, x2, y2); + } + + BOOL Rectangle(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + + BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3) + { + ATLASSERT(m_hDC != NULL); + return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3); + } + + BOOL RoundRect(LPCRECT lpRect, POINT point) + { + ATLASSERT(m_hDC != NULL); + return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y); + } + +// Bitmap Functions + BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop); + } + + BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, + int xSrc, int ySrc, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop); + } + + BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop); + } + + COLORREF GetPixel(int x, int y) const + { + ATLASSERT(m_hDC != NULL); + return ::GetPixel(m_hDC, x, y); + } + + COLORREF GetPixel(POINT point) const + { + ATLASSERT(m_hDC != NULL); + return ::GetPixel(m_hDC, point.x, point.y); + } + + COLORREF SetPixel(int x, int y, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixel(m_hDC, x, y, crColor); + } + + COLORREF SetPixel(POINT point, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixel(m_hDC, point.x, point.y, crColor); + } + +#ifndef _WIN32_WCE + BOOL FloodFill(int x, int y, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::FloodFill(m_hDC, x, y, crColor); + } + + BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) + { + ATLASSERT(m_hDC != NULL); + return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType); + } +#endif // !_WIN32_WCE + + BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop); + } + +#ifndef _WIN32_WCE + BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask) + { + ATLASSERT(m_hDC != NULL); + return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask); + } + + BOOL SetPixelV(int x, int y, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixelV(m_hDC, x, y, crColor); + } + + BOOL SetPixelV(POINT point, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixelV(m_hDC, point.x, point.y, crColor); + } +#endif // !_WIN32_WCE + +#if !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE) +#ifndef _WIN32_WCE + BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent) + { + ATLASSERT(m_hDC != NULL); + return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent); + } +#else // CE specific + BOOL TransparentImage(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent) + { + ATLASSERT(m_hDC != NULL); + return ::TransparentImage(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent); + } +#endif // _WIN32_WCE + +#if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420)) + BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode) + { + ATLASSERT(m_hDC != NULL); + return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + +#if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500) + BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf) + { + ATLASSERT(m_hDC != NULL); + return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500) +#endif // !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE) + +// Extra bitmap functions + // Helper function for painting a disabled toolbar or menu bitmap + // This function can take either an HBITMAP (for SS) or a DC with + // the bitmap already painted (for cmdbar) + BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc, + HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE), + HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT), + HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW)) + { + ATLASSERT(m_hDC != NULL || hBitmap != NULL); + ATLASSERT(nWidth > 0 && nHeight > 0); + + // Create a generic DC for all BitBlts + CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC); + ATLASSERT(dc.m_hDC != NULL); + if(dc.m_hDC == NULL) + return FALSE; + + // Create a DC for the monochrome DIB section + CDC dcBW = ::CreateCompatibleDC(m_hDC); + ATLASSERT(dcBW.m_hDC != NULL); + if(dcBW.m_hDC == NULL) + { + if(hSrcDC == NULL) + dc.DeleteDC(); + return FALSE; + } + + // Create the monochrome DIB section with a black and white palette + struct RGBBWBITMAPINFO + { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[2]; + }; + + RGBBWBITMAPINFO rgbBWBitmapInfo = + { + { sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 }, + { { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } } + }; + + VOID* pbitsBW; + CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0); + ATLASSERT(bmpBW.m_hBitmap != NULL); + if(bmpBW.m_hBitmap == NULL) + { + if(hSrcDC == NULL) + dc.DeleteDC(); + return FALSE; + } + + // Attach the monochrome DIB section and the bitmap to the DCs + HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW); + HBITMAP hbmOldDC = NULL; + if(hBitmap != NULL) + hbmOldDC = dc.SelectBitmap(hBitmap); + + // Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white + { + CDC dcTemp1 = ::CreateCompatibleDC(m_hDC); + CDC dcTemp2 = ::CreateCompatibleDC(m_hDC); + CBitmap bmpTemp1; + bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight); + CBitmap bmpTemp2; + bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL); + HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1); + HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2); + // Let's copy our image, it will be altered + dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY); + + // All dark gray pixels will become white, the others black + dcTemp1.SetBkColor(RGB(128, 128, 128)); + dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY); + // Do an XOR to set to black these white pixels + dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT); + + // BitBlt the bitmap into the monochrome DIB section + // The DIB section will do a true monochrome conversion + // The magenta background being closer to white will become white + dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY); + + // Cleanup + dcTemp1.SelectBitmap(hOldBmp1); + dcTemp2.SelectBitmap(hOldBmp2); + } + + // Paint the destination rectangle using hBrushBackground + if(hBrushBackground != NULL) + { + RECT rc = { x, y, x + nWidth, y + nHeight }; + FillRect(&rc, hBrushBackground); + } + + // BitBlt the black bits in the monochrome bitmap into hBrush3DEffect color in the destination DC + // The magic ROP comes from the Charles Petzold's book + HBRUSH hOldBrush = SelectBrush(hBrush3DEffect); + BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A); + + // BitBlt the black bits in the monochrome bitmap into hBrushDisabledImage color in the destination DC + SelectBrush(hBrushDisabledImage); + BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A); + + SelectBrush(hOldBrush); + dcBW.SelectBitmap(hbmOldBW); + dc.SelectBitmap(hbmOldDC); + + if(hSrcDC == NULL) + dc.DeleteDC(); + + return TRUE; + } + +// Text Functions +#ifndef _WIN32_WCE + BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1) + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::TextOut(m_hDC, x, y, lpszString, nCount); + } +#endif // !_WIN32_WCE + + BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL) + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths); + } + +#ifndef _WIN32_WCE + SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0) + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin); + SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) }; + return size; + } +#endif // !_WIN32_WCE + + int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + ATLASSERT((uFormat & DT_MODIFYSTRING) == 0); +#endif // !_WIN32_WCE + return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat); + } + + int DrawText(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat) + { + ATLASSERT(m_hDC != NULL); + return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat); + } + +#ifndef _WIN32_WCE + int DrawTextEx(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpDTParams = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawTextEx(m_hDC, lpstrText, cchText, lpRect, uFormat, lpDTParams); + } +#endif // !_WIN32_WCE + +#if (_WIN32_WINNT >= 0x0501) + int DrawShadowText(LPCWSTR lpstrText, int cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset) + { + ATLASSERT(m_hDC != NULL); + // This function is present only if comctl32.dll version 6 is loaded; + // we use LoadLibrary/GetProcAddress to allow apps compiled with + // _WIN32_WINNT >= 0x0501 to run on older Windows/CommCtrl + int nRet = 0; + HMODULE hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); + ATLASSERT(hCommCtrlDLL != NULL); + if(hCommCtrlDLL != NULL) + { + typedef int (WINAPI *PFN_DrawShadowText)(HDC hDC, LPCWSTR lpstrText, UINT cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset); + PFN_DrawShadowText pfnDrawShadowText = (PFN_DrawShadowText)::GetProcAddress(hCommCtrlDLL, "DrawShadowText"); + ATLASSERT(pfnDrawShadowText != NULL); // this function requires CommCtrl6 + if(pfnDrawShadowText != NULL) + nRet = pfnDrawShadowText(m_hDC, lpstrText, cchText, lpRect, dwFlags, clrText, clrShadow, xOffset, yOffset); + ::FreeLibrary(hCommCtrlDLL); + } + return nRet; + } +#endif // (_WIN32_WINNT >= 0x0501) + + BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize); + } + + BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::GetTextExtentExPoint(m_hDC, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize); + } + +#ifndef _WIN32_WCE + DWORD GetTabbedTextExtent(LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL) const + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions); + } + + BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) + { + ATLASSERT(m_hDC != NULL); + return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight); + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + UINT GetTextAlign() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextAlign(m_hDC); + } + + UINT SetTextAlign(UINT nFlags) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextAlign(m_hDC, nFlags); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + + int GetTextFace(LPTSTR lpszFacename, int nCount) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextFace(m_hDC, nCount, lpszFacename); + } + + int GetTextFaceLen() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextFace(m_hDC, 0, NULL); + } + +#ifndef _ATL_NO_COM +#ifdef _OLEAUTO_H_ + BOOL GetTextFace(BSTR& bstrFace) const + { + USES_CONVERSION; + ATLASSERT(m_hDC != NULL); + ATLASSERT(bstrFace == NULL); + + int nLen = GetTextFaceLen(); + if(nLen == 0) + return FALSE; + + CTempBuffer buff; + LPTSTR lpszText = buff.Allocate(nLen); + if(lpszText == NULL) + return FALSE; + + if(!GetTextFace(lpszText, nLen)) + return FALSE; + + bstrFace = ::SysAllocString(T2OLE(lpszText)); + return (bstrFace != NULL) ? TRUE : FALSE; + } +#endif +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetTextFace(_CSTRING_NS::CString& strFace) const + { + ATLASSERT(m_hDC != NULL); + + int nLen = GetTextFaceLen(); + if(nLen == 0) + return 0; + + LPTSTR lpstr = strFace.GetBufferSetLength(nLen); + if(lpstr == NULL) + return 0; + int nRet = GetTextFace(lpstr, nLen); + strFace.ReleaseBuffer(); + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextMetrics(m_hDC, lpMetrics); + } + +#ifndef _WIN32_WCE + int SetTextJustification(int nBreakExtra, int nBreakCount) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount); + } + + int GetTextCharacterExtra() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextCharacterExtra(m_hDC); + } + + int SetTextCharacterExtra(int nCharExtra) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextCharacterExtra(m_hDC, nCharExtra); + } +#endif // !_WIN32_WCE + +// Advanced Drawing + BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags) + { + ATLASSERT(m_hDC != NULL); + return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags); + } + + BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState) + { + ATLASSERT(m_hDC != NULL); + return ::DrawFrameControl(m_hDC, lpRect, nType, nState); + } + +// Scrolling Functions + BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate) + { + ATLASSERT(m_hDC != NULL); + return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate); + } + +// Font Functions +#ifndef _WIN32_WCE + BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer); + } + + // GetCharWidth32 is not supported under Win9x + BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer); + } + + DWORD SetMapperFlags(DWORD dwFlag) + { + ATLASSERT(m_hDC != NULL); + return ::SetMapperFlags(m_hDC, dwFlag); + } + + BOOL GetAspectRatioFilter(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetAspectRatioFilterEx(m_hDC, lpSize); + } + + BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc); + } + + DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const + { + ATLASSERT(m_hDC != NULL); + return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData); + } + + int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const + { + ATLASSERT(m_hDC != NULL); + return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair); + } + + UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const + { + ATLASSERT(m_hDC != NULL); + return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm); + } + + DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const + { + ATLASSERT(m_hDC != NULL); + return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2); + } + + BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF); + } + + BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer); + } +#endif // !_WIN32_WCE + +// Printer/Device Escape Functions +#ifndef _WIN32_WCE + int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData) + { + ATLASSERT(m_hDC != NULL); + return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData); + } +#endif // !_WIN32_WCE + + int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData, + int nOutputSize, LPSTR lpszOutputData) + { + ATLASSERT(m_hDC != NULL); + return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData); + } + +#ifndef _WIN32_WCE + int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData) + { + ATLASSERT(m_hDC != NULL); + return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData); + } +#endif // !_WIN32_WCE + + // Escape helpers +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc)) + int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version + { + DOCINFO di = { 0 }; + di.cbSize = sizeof(DOCINFO); + di.lpszDocName = lpszDocName; + return StartDoc(&di); + } + + int StartDoc(LPDOCINFO lpDocInfo) + { + ATLASSERT(m_hDC != NULL); + return ::StartDoc(m_hDC, lpDocInfo); + } + + int StartPage() + { + ATLASSERT(m_hDC != NULL); + return ::StartPage(m_hDC); + } + + int EndPage() + { + ATLASSERT(m_hDC != NULL); + return ::EndPage(m_hDC); + } + + int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) + { + ATLASSERT(m_hDC != NULL); + return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn); + } + + int AbortDoc() + { + ATLASSERT(m_hDC != NULL); + return ::AbortDoc(m_hDC); + } + + int EndDoc() + { + ATLASSERT(m_hDC != NULL); + return ::EndDoc(m_hDC); + } +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc)) + +// MetaFile Functions +#ifndef _WIN32_WCE + BOOL PlayMetaFile(HMETAFILE hMF) + { + ATLASSERT(m_hDC != NULL); + if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE) + { + // playing metafile in metafile, just use core windows API + return ::PlayMetaFile(m_hDC, hMF); + } + + // for special playback, lParam == pDC + return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this); + } + + BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds) + { + ATLASSERT(m_hDC != NULL); + return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds); + } + + BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only + { + ATLASSERT(m_hDC != NULL); + return ::GdiComment(m_hDC, nDataSize, pCommentData); + } + + // Special handling for metafile playback + static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam) + { + CDCHandle* pDC = (CDCHandle*)lParam; + + switch (pMetaRec->rdFunction) + { + case META_SETMAPMODE: + pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]); + break; + case META_SETWINDOWEXT: + pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SETWINDOWORG: + pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SETVIEWPORTEXT: + pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SETVIEWPORTORG: + pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SCALEWINDOWEXT: + pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2], + (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SCALEVIEWPORTEXT: + pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2], + (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_OFFSETVIEWPORTORG: + pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SAVEDC: + pDC->SaveDC(); + break; + case META_RESTOREDC: + pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]); + break; + case META_SETBKCOLOR: + pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]); + break; + case META_SETTEXTCOLOR: + pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]); + break; + + // need to watch out for SelectObject(HFONT), for custom font mapping + case META_SELECTOBJECT: + { + HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]]; + UINT nObjType = ::GetObjectType(hObject); + if(nObjType == 0) + { + // object type is unknown, determine if it is a font + HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT); + HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont); + HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject); + if(hObjOld == hStockFont) + { + // got the stock object back, so must be selecting a font + pDC->SelectFont((HFONT)hObject); + break; // don't play the default record + } + else + { + // didn't get the stock object back, so restore everything + ::SelectObject(pDC->m_hDC, hFontOld); + ::SelectObject(pDC->m_hDC, hObjOld); + } + // and fall through to PlayMetaFileRecord... + } + else if(nObjType == OBJ_FONT) + { + // play back as CDCHandle::SelectFont(HFONT) + pDC->SelectFont((HFONT)hObject); + break; // don't play the default record + } + } + // fall through... + + default: + ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles); + break; + } + + return 1; + } +#endif // !_WIN32_WCE + +// Path Functions +#ifndef _WIN32_WCE + BOOL AbortPath() + { + ATLASSERT(m_hDC != NULL); + return ::AbortPath(m_hDC); + } + + BOOL BeginPath() + { + ATLASSERT(m_hDC != NULL); + return ::BeginPath(m_hDC); + } + + BOOL CloseFigure() + { + ATLASSERT(m_hDC != NULL); + return ::CloseFigure(m_hDC); + } + + BOOL EndPath() + { + ATLASSERT(m_hDC != NULL); + return ::EndPath(m_hDC); + } + + BOOL FillPath() + { + ATLASSERT(m_hDC != NULL); + return ::FillPath(m_hDC); + } + + BOOL FlattenPath() + { + ATLASSERT(m_hDC != NULL); + return ::FlattenPath(m_hDC); + } + + BOOL StrokeAndFillPath() + { + ATLASSERT(m_hDC != NULL); + return ::StrokeAndFillPath(m_hDC); + } + + BOOL StrokePath() + { + ATLASSERT(m_hDC != NULL); + return ::StrokePath(m_hDC); + } + + BOOL WidenPath() + { + ATLASSERT(m_hDC != NULL); + return ::WidenPath(m_hDC); + } + + BOOL GetMiterLimit(PFLOAT pfMiterLimit) const + { + ATLASSERT(m_hDC != NULL); + return ::GetMiterLimit(m_hDC, pfMiterLimit); + } + + BOOL SetMiterLimit(float fMiterLimit) + { + ATLASSERT(m_hDC != NULL); + return ::SetMiterLimit(m_hDC, fMiterLimit, NULL); + } + + int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const + { + ATLASSERT(m_hDC != NULL); + return ::GetPath(m_hDC, lpPoints, lpTypes, nCount); + } + + BOOL SelectClipPath(int nMode) + { + ATLASSERT(m_hDC != NULL); + return ::SelectClipPath(m_hDC, nMode); + } +#endif // !_WIN32_WCE + +// Misc Helper Functions + static CBrushHandle PASCAL GetHalftoneBrush() + { + HBRUSH halftoneBrush = NULL; + WORD grayPattern[8]; + for(int i = 0; i < 8; i++) + grayPattern[i] = (WORD)(0x5555 << (i & 1)); + HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern); + if(grayBitmap != NULL) + { + halftoneBrush = ::CreatePatternBrush(grayBitmap); + DeleteObject(grayBitmap); + } + return CBrushHandle(halftoneBrush); + } + + void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL) + { + // first, determine the update region and select it + CRgn rgnOutside; + rgnOutside.CreateRectRgnIndirect(lpRect); + RECT rect = *lpRect; + ::InflateRect(&rect, -size.cx, -size.cy); + ::IntersectRect(&rect, &rect, lpRect); + CRgn rgnInside; + rgnInside.CreateRectRgnIndirect(&rect); + CRgn rgnNew; + rgnNew.CreateRectRgn(0, 0, 0, 0); + rgnNew.CombineRgn(rgnOutside, rgnInside, RGN_XOR); + + HBRUSH hBrushOld = NULL; + CBrush brushHalftone; + if(hBrush == NULL) + brushHalftone = hBrush = CDCHandle::GetHalftoneBrush(); + if(hBrushLast == NULL) + hBrushLast = hBrush; + + CRgn rgnLast; + CRgn rgnUpdate; + if(lpRectLast != NULL) + { + // find difference between new region and old region + rgnLast.CreateRectRgn(0, 0, 0, 0); + rgnOutside.SetRectRgn(lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom); + rect = *lpRectLast; + ::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy); + ::IntersectRect(&rect, &rect, lpRectLast); + rgnInside.SetRectRgn(rect.left, rect.top, rect.right, rect.bottom); + rgnLast.CombineRgn(rgnOutside, rgnInside, RGN_XOR); + + // only diff them if brushes are the same + if(hBrush == hBrushLast) + { + rgnUpdate.CreateRectRgn(0, 0, 0, 0); + rgnUpdate.CombineRgn(rgnLast, rgnNew, RGN_XOR); + } + } + if(hBrush != hBrushLast && lpRectLast != NULL) + { + // brushes are different -- erase old region first + SelectClipRgn(rgnLast); + GetClipBox(&rect); + hBrushOld = SelectBrush(hBrushLast); + PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); + SelectBrush(hBrushOld); + hBrushOld = NULL; + } + + // draw into the update/new region + SelectClipRgn(rgnUpdate.IsNull() ? rgnNew : rgnUpdate); + GetClipBox(&rect); + hBrushOld = SelectBrush(hBrush); + PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); + + // cleanup DC + if(hBrushOld != NULL) + SelectBrush(hBrushOld); + SelectClipRgn(NULL); + } + + void FillSolidRect(LPCRECT lpRect, COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + + COLORREF clrOld = ::SetBkColor(m_hDC, clr); + ATLASSERT(clrOld != CLR_INVALID); + if(clrOld != CLR_INVALID) + { + ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); + ::SetBkColor(m_hDC, clrOld); + } + } + + void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + + RECT rect = { x, y, x + cx, y + cy }; + FillSolidRect(&rect, clr); + } + + void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) + { + Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left, + lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight); + } + + void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight) + { + FillSolidRect(x, y, cx - 1, 1, clrTopLeft); + FillSolidRect(x, y, 1, cy - 1, clrTopLeft); + FillSolidRect(x + cx, y, -1, cy, clrBottomRight); + FillSolidRect(x, y + cy, cx, -1, clrBottomRight); + } + +// DIB support +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) + { + ATLASSERT(m_hDC != NULL); + return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop); + } + + UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const + { + ATLASSERT(m_hDC != NULL); + return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors); + } + + UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors) + { + ATLASSERT(m_hDC != NULL); + return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + +// OpenGL support +#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd) + { + ATLASSERT(m_hDC != NULL); + return ::ChoosePixelFormat(m_hDC, ppfd); + } + + int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd) + { + ATLASSERT(m_hDC != NULL); + return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd); + } + + int GetPixelFormat() const + { + ATLASSERT(m_hDC != NULL); + return ::GetPixelFormat(m_hDC); + } + + BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd); + } + + BOOL SwapBuffers() + { + ATLASSERT(m_hDC != NULL); + return ::SwapBuffers(m_hDC); + } + + HGLRC wglCreateContext() + { + ATLASSERT(m_hDC != NULL); + return ::wglCreateContext(m_hDC); + } + + HGLRC wglCreateLayerContext(int iLayerPlane) + { + ATLASSERT(m_hDC != NULL); + return ::wglCreateLayerContext(m_hDC, iLayerPlane); + } + + BOOL wglMakeCurrent(HGLRC hglrc) + { + ATLASSERT(m_hDC != NULL); + return ::wglMakeCurrent(m_hDC, hglrc); + } + + BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase) + { + ATLASSERT(m_hDC != NULL); + return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase); + } + + BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) + { + ATLASSERT(m_hDC != NULL); + return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf); + } + + BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd) + { + ATLASSERT(m_hDC != NULL); + return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd); + } + + int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr) + { + ATLASSERT(m_hDC != NULL); + return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr); + } + + int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr) + { + ATLASSERT(m_hDC != NULL); + return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr); + } + + BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize) + { + ATLASSERT(m_hDC != NULL); + return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize); + } + + BOOL wglSwapLayerBuffers(UINT uPlanes) + { + ATLASSERT(m_hDC != NULL); + return ::wglSwapLayerBuffers(m_hDC, uPlanes); + } +#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + +// New for Windows 2000 only +#if (_WIN32_WINNT >= 0x0500) + COLORREF GetDCPenColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetDCPenColor(m_hDC); + } + + COLORREF SetDCPenColor(COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + return ::SetDCPenColor(m_hDC, clr); + } + + COLORREF GetDCBrushColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetDCBrushColor(m_hDC); + } + + COLORREF SetDCBrushColor(COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + return ::SetDCBrushColor(m_hDC, clr); + } + +#ifndef _WIN32_WCE + DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const + { + ATLASSERT(m_hDC != NULL); + return ::GetFontUnicodeRanges(m_hDC, lpgs); + } +#endif // !_WIN32_WCE + + DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const + { + ATLASSERT(m_hDC != NULL); + return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags); + } + + BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize); + } + + BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize); + } + + BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer); + } + + BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc); + } +#endif // (_WIN32_WINNT >= 0x0500) + +// New for Windows 2000 and Windows 98 +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries) + { + ATLASSERT(m_hDC != NULL); + return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CDCT CDCHandle; +typedef CDCT CDC; + + +/////////////////////////////////////////////////////////////////////////////// +// CDC Helpers + +class CPaintDC : public CDC +{ +public: +// Data members + HWND m_hWnd; + PAINTSTRUCT m_ps; + +// Constructor/destructor + CPaintDC(HWND hWnd) + { + ATLASSERT(::IsWindow(hWnd)); + m_hWnd = hWnd; + m_hDC = ::BeginPaint(hWnd, &m_ps); + } + + ~CPaintDC() + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(::IsWindow(m_hWnd)); + ::EndPaint(m_hWnd, &m_ps); + Detach(); + } +}; + +class CClientDC : public CDC +{ +public: +// Data members + HWND m_hWnd; + +// Constructor/destructor + CClientDC(HWND hWnd) + { + ATLASSERT(hWnd == NULL || ::IsWindow(hWnd)); + m_hWnd = hWnd; + m_hDC = ::GetDC(hWnd); + } + + ~CClientDC() + { + ATLASSERT(m_hDC != NULL); + ::ReleaseDC(m_hWnd, Detach()); + } +}; + +class CWindowDC : public CDC +{ +public: +// Data members + HWND m_hWnd; + +// Constructor/destructor + CWindowDC(HWND hWnd) + { + ATLASSERT(hWnd == NULL || ::IsWindow(hWnd)); + m_hWnd = hWnd; + m_hDC = ::GetWindowDC(hWnd); + } + + ~CWindowDC() + { + ATLASSERT(m_hDC != NULL); + ::ReleaseDC(m_hWnd, Detach()); + } +}; + +class CMemoryDC : public CDC +{ +public: +// Data members + HDC m_hDCOriginal; + RECT m_rcPaint; + CBitmap m_bmp; + HBITMAP m_hBmpOld; + +// Constructor/destructor + CMemoryDC(HDC hDC, RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL) + { + m_rcPaint = rcPaint; + CreateCompatibleDC(m_hDCOriginal); + ATLASSERT(m_hDC != NULL); + m_bmp.CreateCompatibleBitmap(m_hDCOriginal, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top); + ATLASSERT(m_bmp.m_hBitmap != NULL); + m_hBmpOld = SelectBitmap(m_bmp); + SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top); + } + + ~CMemoryDC() + { + ::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY); + SelectBitmap(m_hBmpOld); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Enhanced metafile support + +#ifndef _WIN32_WCE + +class CEnhMetaFileInfo +{ +public: +// Data members + HENHMETAFILE m_hEMF; + BYTE* m_pBits; + TCHAR* m_pDesc; + ENHMETAHEADER m_header; + PIXELFORMATDESCRIPTOR m_pfd; + +// Constructor/destructor + CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF) + { } + + ~CEnhMetaFileInfo() + { + delete [] m_pBits; + delete [] m_pDesc; + } + +// Operations + BYTE* GetEnhMetaFileBits() + { + ATLASSERT(m_hEMF != NULL); + UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL); + delete [] m_pBits; + m_pBits = NULL; + ATLTRY(m_pBits = new BYTE[nBytes]); + if (m_pBits != NULL) + ::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits); + return m_pBits; + } + + LPTSTR GetEnhMetaFileDescription() + { + ATLASSERT(m_hEMF != NULL); + UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL); + delete [] m_pDesc; + m_pDesc = NULL; + ATLTRY(m_pDesc = new TCHAR[nLen]); + if (m_pDesc != NULL) + nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc); + return m_pDesc; + } + + ENHMETAHEADER* GetEnhMetaFileHeader() + { + ATLASSERT(m_hEMF != NULL); + memset(&m_header, 0, sizeof(m_header)); + m_header.iType = EMR_HEADER; + m_header.nSize = sizeof(ENHMETAHEADER); + UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header); + return (n != 0) ? &m_header : NULL; + } + + PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat() + { + ATLASSERT(m_hEMF != NULL); + memset(&m_pfd, 0, sizeof(m_pfd)); + UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd); + return (n != 0) ? &m_pfd : NULL; + } +}; + + +template +class CEnhMetaFileT +{ +public: +// Data members + HENHMETAFILE m_hEMF; + +// Constructor/destructor + CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF) + { + } + + ~CEnhMetaFileT() + { + if(t_bManaged && m_hEMF != NULL) + DeleteObject(); + } + +// Operations + CEnhMetaFileT& operator =(HENHMETAFILE hEMF) + { + Attach(hEMF); + return *this; + } + + void Attach(HENHMETAFILE hEMF) + { + if(t_bManaged && m_hEMF != NULL && m_hEMF != hEMF) + DeleteObject(); + m_hEMF = hEMF; + } + + HENHMETAFILE Detach() + { + HENHMETAFILE hEMF = m_hEMF; + m_hEMF = NULL; + return hEMF; + } + + operator HENHMETAFILE() const { return m_hEMF; } + + bool IsNull() const { return (m_hEMF == NULL); } + + BOOL DeleteObject() + { + ATLASSERT(m_hEMF != NULL); + BOOL bRet = ::DeleteEnhMetaFile(m_hEMF); + m_hEMF = NULL; + return bRet; + } + + UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer); + } + + UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription); + } + + UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const + { + ATLASSERT(m_hEMF != NULL); + lpemh->iType = EMR_HEADER; + lpemh->nSize = sizeof(ENHMETAHEADER); + return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh); + } + + UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe); + } + + UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd); + } +}; + +typedef CEnhMetaFileT CEnhMetaFileHandle; +typedef CEnhMetaFileT CEnhMetaFile; + + +class CEnhMetaFileDC : public CDC +{ +public: +// Constructor/destructor + CEnhMetaFileDC() + { + } + + CEnhMetaFileDC(HDC hdc, LPCRECT lpRect) + { + Create(hdc, NULL, lpRect, NULL); + ATLASSERT(m_hDC != NULL); + } + + CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription) + { + Create(hdcRef, lpFilename, lpRect, lpDescription); + ATLASSERT(m_hDC != NULL); + } + + ~CEnhMetaFileDC() + { + HENHMETAFILE hEMF = Close(); + if (hEMF != NULL) + ::DeleteEnhMetaFile(hEMF); + } + +// Operations + void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription) + { + ATLASSERT(m_hDC == NULL); + m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription); + } + + HENHMETAFILE Close() + { + HENHMETAFILE hEMF = NULL; + if (m_hDC != NULL) + { + hEMF = ::CloseEnhMetaFile(m_hDC); + m_hDC = NULL; + } + return hEMF; + } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// WinCE compatible clipboard CF_DIB format support functions + +#ifndef _WTL_NO_DIB16 + +#define DIBINFO16_BITFIELDS { 31744, 992, 31 } + +// DIBINFO16 - To avoid color table problems in WinCE we only create this type of Dib +struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields +{ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[3]; + + DIBINFO16(SIZE size) + { + BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), size.cx, size.cy, + 1, 16, BI_BITFIELDS, 2 * size.cx * size.cy , 0, 0, 3 }; + DWORD dw[3] = DIBINFO16_BITFIELDS ; + + bmiHeader = bmih; + memcpy(bmiColors, dw, 3 * sizeof(DWORD)); + } +}; + + +// AtlxxxDibxxx minimal packed DIB implementation and helpers to copy and paste CF_DIB + +inline bool AtlIsDib16(LPBITMAPINFOHEADER pbmih) +{ + return (pbmih->biBitCount == 16) && (pbmih->biCompression == BI_BITFIELDS); +} + +inline int AtlGetDibColorTableSize(LPBITMAPINFOHEADER pbmih) +{ + switch (pbmih->biBitCount) + { + case 2: + case 4: + case 8: + return pbmih->biClrUsed ? pbmih->biClrUsed : 1 << pbmih->biBitCount; + case 24: + break; + case 16: + case 32: + return pbmih->biCompression == BI_BITFIELDS ? 3 : 0; + default: + ATLASSERT(FALSE); // should never come here + } + + return 0; +} + +inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih) +{ + switch (pbmih->biBitCount) + { + case 2: + case 4: + case 8: + if (pbmih->biClrUsed) + return pbmih->biClrUsed; + else + break; + case 16: + if (pbmih->biCompression == BI_BITFIELDS ) + return 1 << 15; + else + break; + case 24: + break; + case 32: + if (pbmih->biCompression == BI_BITFIELDS ) + return 1 << 24; + else + break; + default: + ATLASSERT(FALSE); + } + + return 1 << pbmih->biBitCount; +} + +inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi) +{ + HBITMAP hbm = NULL; + CDC dc(NULL); + void * pBits = NULL; + + LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD); + if (hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL)) + memcpy(pBits, pDibBits, pbmi->bmiHeader.biSizeImage); + + return hbm; +} + +inline HBITMAP AtlCopyBitmap(HBITMAP hbm , SIZE sizeDst, bool bAsBitmap = false) +{ + CDC hdcSrc = CreateCompatibleDC(NULL); + CDC hdcDst = CreateCompatibleDC(NULL); + + CBitmapHandle hbmOld = NULL, hbmOld2 = NULL, bmSrc = hbm; + + CBitmap bmNew = NULL; + + SIZE sizeSrc = { 0 }; + bmSrc.GetSize(sizeSrc); + + hbmOld = hdcSrc.SelectBitmap(bmSrc); + + if (bAsBitmap) + { + bmNew.CreateCompatibleBitmap(hdcSrc, sizeDst.cx, sizeDst.cy); + } + else + { + DIBINFO16 dib16(sizeDst); + LPVOID pBits = NULL; + bmNew = CreateDIBSection(hdcDst, (const BITMAPINFO*)&dib16, DIB_RGB_COLORS, &pBits, NULL, NULL); + } + + ATLASSERT(!bmNew.IsNull()); + + hbmOld2 = hdcDst.SelectBitmap(bmNew); + BOOL bOK = FALSE; + + if ((sizeDst.cx == sizeSrc.cx) && (sizeDst.cy == sizeSrc.cy)) + bOK = hdcDst.BitBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, SRCCOPY); + else + bOK = hdcDst.StretchBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, sizeSrc.cx, sizeSrc.cy, SRCCOPY); + + hdcSrc.SelectBitmap(hbmOld); + hdcDst.SelectBitmap(hbmOld2); + + if (bOK == FALSE) + bmNew.DeleteObject(); + + return bmNew.Detach(); +} + +inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size) +{ + DIBSECTION ds = { 0 }; + LPBYTE pDib = NULL; + bool bCopied = false; + + bool bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds); + if ((bOK == FALSE) || (ds.dsBm.bmBits == NULL) || (AtlIsDib16(&ds.dsBmih) == FALSE) || + (ds.dsBmih.biWidth != size.cx ) || (ds.dsBmih.biHeight != size.cy )) + { + if ((hbm = AtlCopyBitmap(hbm, size)) != NULL) + { + bCopied = true; + bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds); + } + else + { + bOK = FALSE; + } + } + + if((bOK == TRUE) && (AtlIsDib16(&ds.dsBmih) == TRUE) && (ds.dsBm.bmBits != NULL)) + { + pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage); + if (pDib != NULL) + { + memcpy(pDib , &ds.dsBmih, sizeof(DIBINFO16)); + memcpy(pDib + sizeof(DIBINFO16), ds.dsBm.bmBits, ds.dsBmih.biSizeImage); + } + } + + if (bCopied == true) + DeleteObject(hbm); + + return (HLOCAL)pDib; +} + +inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd) +{ + ATLASSERT(::IsWindow(hWnd)); + BOOL bOK = OpenClipboard(hWnd); + if (bOK == TRUE) + { + if ((bOK = EmptyClipboard()) == TRUE) + { + HLOCAL hDib = AtlCreatePackedDib16(hbm, size); + if (hDib != NULL) + { + bOK = SetClipboardData(CF_DIB, hDib) != NULL; + if (bOK == FALSE) + LocalFree(hDib); + } + else + { + bOK = FALSE; + } + } + CloseClipboard(); + } + + return bOK == TRUE; +} + +inline HBITMAP AtlGetClipboardDib(HWND hWnd) +{ + ATLASSERT(::IsWindow(hWnd) == TRUE); + HBITMAP hbm = NULL; + if (OpenClipboard(hWnd) == TRUE) + { + LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB); + if (pbmi != NULL) + hbm = AtlGetDibBitmap(pbmi); + CloseClipboard(); + } + + return hbm; +} + +#endif // _WTL_NO_DIB16 + +}; // namespace WTL + +#endif // __ATLGDI_H__ diff --git a/ext/CrashServer/external/WTL/Include/atlres.h b/ext/CrashServer/external/WTL/Include/atlres.h new file mode 100644 index 000000000..6da9ab068 --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atlres.h @@ -0,0 +1,262 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLRES_H__ +#define __ATLRES_H__ + +#pragma once + +#if defined(_WIN32_WCE) && !defined(__ATLRESCE_H__) + #error Use atlresCE.h instead of atlres.h for Windows CE +#endif + + +#ifdef RC_INVOKED +#ifndef _INC_WINDOWS + + #define _INC_WINDOWS + + #ifndef _WIN32_WCE + #define VS_VERSION_INFO 1 + + #ifdef APSTUDIO_INVOKED + #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols + #endif // APSTUDIO_INVOKED + + #ifndef WINVER + #define WINVER 0x0400 // default to Windows Version 4.0 + #endif // !WINVER + + #include + + // operation messages sent to DLGINIT + #define LB_ADDSTRING (WM_USER+1) + #define CB_ADDSTRING (WM_USER+3) + #endif // !_WIN32_WCE + + #ifdef APSTUDIO_INVOKED + #undef APSTUDIO_HIDDEN_SYMBOLS + #endif // APSTUDIO_INVOKED + + #ifdef IDC_STATIC + #undef IDC_STATIC + #endif // IDC_STATIC + #define IDC_STATIC (-1) + +#endif // !_INC_WINDOWS +#endif // RC_INVOKED + +#ifdef APSTUDIO_INVOKED + #define APSTUDIO_HIDDEN_SYMBOLS +#endif // APSTUDIO_INVOKED + +/////////////////////////////////////////////////////////////////////////////// +// ATL resource types + +#ifndef RC_INVOKED + #define RT_DLGINIT MAKEINTRESOURCE(240) + #define RT_TOOLBAR MAKEINTRESOURCE(241) +#endif // RC_INVOKED + +/////////////////////////////////////////////////////////////////////////////// + +#ifdef APSTUDIO_INVOKED + #undef APSTUDIO_HIDDEN_SYMBOLS +#endif // APSTUDIO_INVOKED + +/////////////////////////////////////////////////////////////////////////////// +// Standard window components + +#define ID_SEPARATOR 0 // special separator value +#define ID_DEFAULT_PANE 0 // default status bar pane + +#ifndef RC_INVOKED // code only +// standard control bars (IDW = window ID) + #define ATL_IDW_TOOLBAR 0xE800 // main Toolbar for window + #define ATL_IDW_STATUS_BAR 0xE801 // Status bar window + #define ATL_IDW_COMMAND_BAR 0xE802 // Command bar window + +// parts of a frame window + #define ATL_IDW_CLIENT 0xE900 + #define ATL_IDW_PANE_FIRST 0xE900 // first pane (256 max) + #define ATL_IDW_PANE_LAST 0xE9FF + #define ATL_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max) + #define ATL_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max) + + #define ATL_IDW_SIZE_BOX 0xEA20 // size box for splitters + #define ATL_IDW_PANE_SAVE 0xEA21 // to shift ATL_IDW_PANE_FIRST + +// bands for a rebar + #define ATL_IDW_BAND_FIRST 0xEB00 + #define ATL_IDW_BAND_LAST 0xEBFF +#endif // !RC_INVOKED + +/////////////////////////////////////////////////////////////////////////////// +// Standard Commands + +// File commands +#define ID_FILE_NEW 0xE100 +#define ID_FILE_OPEN 0xE101 +#define ID_FILE_CLOSE 0xE102 +#define ID_FILE_SAVE 0xE103 +#define ID_FILE_SAVE_AS 0xE104 +#define ID_FILE_PAGE_SETUP 0xE105 +#define ID_FILE_PRINT_SETUP 0xE106 +#define ID_FILE_PRINT 0xE107 +#define ID_FILE_PRINT_DIRECT 0xE108 +#define ID_FILE_PRINT_PREVIEW 0xE109 +#define ID_FILE_UPDATE 0xE10A +#define ID_FILE_SAVE_COPY_AS 0xE10B +#define ID_FILE_SEND_MAIL 0xE10C + +#define ID_FILE_MRU_FIRST 0xE110 +#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max +#define ID_FILE_MRU_FILE2 0xE111 +#define ID_FILE_MRU_FILE3 0xE112 +#define ID_FILE_MRU_FILE4 0xE113 +#define ID_FILE_MRU_FILE5 0xE114 +#define ID_FILE_MRU_FILE6 0xE115 +#define ID_FILE_MRU_FILE7 0xE116 +#define ID_FILE_MRU_FILE8 0xE117 +#define ID_FILE_MRU_FILE9 0xE118 +#define ID_FILE_MRU_FILE10 0xE119 +#define ID_FILE_MRU_FILE11 0xE11A +#define ID_FILE_MRU_FILE12 0xE11B +#define ID_FILE_MRU_FILE13 0xE11C +#define ID_FILE_MRU_FILE14 0xE11D +#define ID_FILE_MRU_FILE15 0xE11E +#define ID_FILE_MRU_FILE16 0xE11F +#define ID_FILE_MRU_LAST 0xE11F + +// Edit commands +#define ID_EDIT_CLEAR 0xE120 +#define ID_EDIT_CLEAR_ALL 0xE121 +#define ID_EDIT_COPY 0xE122 +#define ID_EDIT_CUT 0xE123 +#define ID_EDIT_FIND 0xE124 +#define ID_EDIT_PASTE 0xE125 +#define ID_EDIT_PASTE_LINK 0xE126 +#define ID_EDIT_PASTE_SPECIAL 0xE127 +#define ID_EDIT_REPEAT 0xE128 +#define ID_EDIT_REPLACE 0xE129 +#define ID_EDIT_SELECT_ALL 0xE12A +#define ID_EDIT_UNDO 0xE12B +#define ID_EDIT_REDO 0xE12C + +// Window commands +#define ID_WINDOW_NEW 0xE130 +#define ID_WINDOW_ARRANGE 0xE131 +#define ID_WINDOW_CASCADE 0xE132 +#define ID_WINDOW_TILE_HORZ 0xE133 +#define ID_WINDOW_TILE_VERT 0xE134 +#define ID_WINDOW_SPLIT 0xE135 +#ifndef RC_INVOKED // code only + #define ATL_IDM_WINDOW_FIRST 0xE130 + #define ATL_IDM_WINDOW_LAST 0xE13F + #define ATL_IDM_FIRST_MDICHILD 0xFF00 // window list starts here + #define ATL_IDM_LAST_MDICHILD 0xFFFD +#endif // !RC_INVOKED +// TabView +#define ID_WINDOW_TABFIRST 0xFF00 // = ATL_IDM_FIRST_MDICHILD +#define ID_WINDOW_TABLAST 0xFFFD +#define ID_WINDOW_SHOWTABLIST 0xFFFE + +// Help and App commands +#define ID_APP_ABOUT 0xE140 +#define ID_APP_EXIT 0xE141 +#define ID_HELP_INDEX 0xE142 +#define ID_HELP_FINDER 0xE143 +#define ID_HELP_USING 0xE144 +#define ID_CONTEXT_HELP 0xE145 // shift-F1 +// special commands for processing help +#define ID_HELP 0xE146 // first attempt for F1 +#define ID_DEFAULT_HELP 0xE147 // last attempt + +// Misc +#define ID_NEXT_PANE 0xE150 +#define ID_PREV_PANE 0xE151 +#define ID_PANE_CLOSE 0xE152 + +// Format +#define ID_FORMAT_FONT 0xE160 + +// Scroll +#define ID_SCROLL_UP 0xE170 +#define ID_SCROLL_DOWN 0xE171 +#define ID_SCROLL_PAGE_UP 0xE172 +#define ID_SCROLL_PAGE_DOWN 0xE173 +#define ID_SCROLL_TOP 0xE174 +#define ID_SCROLL_BOTTOM 0xE175 +#define ID_SCROLL_LEFT 0xE176 +#define ID_SCROLL_RIGHT 0xE177 +#define ID_SCROLL_PAGE_LEFT 0xE178 +#define ID_SCROLL_PAGE_RIGHT 0xE179 +#define ID_SCROLL_ALL_LEFT 0xE17A +#define ID_SCROLL_ALL_RIGHT 0xE17B + +// OLE commands +#define ID_OLE_INSERT_NEW 0xE200 +#define ID_OLE_EDIT_LINKS 0xE201 +#define ID_OLE_EDIT_CONVERT 0xE202 +#define ID_OLE_EDIT_CHANGE_ICON 0xE203 +#define ID_OLE_EDIT_PROPERTIES 0xE204 +#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max +#ifndef RC_INVOKED // code only + #define ID_OLE_VERB_LAST 0xE21F +#endif // !RC_INVOKED + +// View commands (same number used as IDW used for toolbar and status bar) +#define ID_VIEW_TOOLBAR 0xE800 +#define ID_VIEW_STATUS_BAR 0xE801 +#define ID_VIEW_REFRESH 0xE803 + +/////////////////////////////////////////////////////////////////////////////// +// Standard control IDs + +#ifdef IDC_STATIC + #undef IDC_STATIC +#endif // IDC_STATIC +#define IDC_STATIC (-1) // all static controls + +/////////////////////////////////////////////////////////////////////////////// +// Standard string error/warnings + +// idle status bar message +#define ATL_IDS_IDLEMESSAGE 0xE001 + +#ifndef RC_INVOKED // code only + #define ATL_IDS_SCFIRST 0xEF00 +#endif // !RC_INVOKED + +#define ATL_IDS_SCSIZE 0xEF00 +#define ATL_IDS_SCMOVE 0xEF01 +#define ATL_IDS_SCMINIMIZE 0xEF02 +#define ATL_IDS_SCMAXIMIZE 0xEF03 +#define ATL_IDS_SCNEXTWINDOW 0xEF04 +#define ATL_IDS_SCPREVWINDOW 0xEF05 +#define ATL_IDS_SCCLOSE 0xEF06 +#define ATL_IDS_SCRESTORE 0xEF12 +#define ATL_IDS_SCTASKLIST 0xEF13 + +#define ATL_IDS_MDICHILD 0xEF1F +#define ATL_IDS_MRU_FILE 0xEFDA + +/////////////////////////////////////////////////////////////////////////////// +// Misc. control IDs + +// Property Sheet control id's (determined with Spy++) +#define ID_APPLY_NOW 0x3021 +#define ID_WIZBACK 0x3023 +#define ID_WIZNEXT 0x3024 +#define ID_WIZFINISH 0x3025 +#define ATL_IDC_TAB_CONTROL 0x3020 + +#endif // __ATLRES_H__ diff --git a/ext/CrashServer/external/WTL/Include/atluser.h b/ext/CrashServer/external/WTL/Include/atluser.h new file mode 100644 index 000000000..01b97e27c --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atluser.h @@ -0,0 +1,1193 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLUSER_H__ +#define __ATLUSER_H__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLAPP_H__ + #error atluser.h requires atlapp.h to be included first +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CMenuItemInfo +// CMenuT +// CAcceleratorT +// CIconT +// CCursorT +// CResource +// +// Global functions: +// AtlMessageBox() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// AtlMessageBox - accepts both memory and resource based strings + +inline int AtlMessageBox(HWND hWndOwner, ATL::_U_STRINGorID message, ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uType = MB_OK | MB_ICONINFORMATION) +{ + ATLASSERT(hWndOwner == NULL || ::IsWindow(hWndOwner)); + + LPTSTR lpstrMessage = NULL; + if(IS_INTRESOURCE(message.m_lpstr)) + { + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrMessage = new TCHAR[nLen]); + if(lpstrMessage == NULL) + { + ATLASSERT(FALSE); + return 0; + } + int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(message.m_lpstr), lpstrMessage, nLen); + if(nRes < nLen - 1) + break; + delete [] lpstrMessage; + lpstrMessage = NULL; + } + + message.m_lpstr = lpstrMessage; + } + + LPTSTR lpstrTitle = NULL; + if(IS_INTRESOURCE(title.m_lpstr) && LOWORD(title.m_lpstr) != 0) + { + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrTitle = new TCHAR[nLen]); + if(lpstrTitle == NULL) + { + ATLASSERT(FALSE); + return 0; + } + int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(title.m_lpstr), lpstrTitle, nLen); + if(nRes < nLen - 1) + break; + delete [] lpstrTitle; + lpstrTitle = NULL; + } + + title.m_lpstr = lpstrTitle; + } + + int nRet = ::MessageBox(hWndOwner, message.m_lpstr, title.m_lpstr, uType); + + delete [] lpstrMessage; + delete [] lpstrTitle; + + return nRet; +} + + +/////////////////////////////////////////////////////////////////////////////// +// CMenu + +#if (WINVER >= 0x0500) + #ifndef MII_SIZEOF_STRUCT + #define MII_SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) + #endif + #define MENUITEMINFO_SIZE_VERSION_400A MII_SIZEOF_STRUCT(MENUITEMINFOA, cch) + #define MENUITEMINFO_SIZE_VERSION_400W MII_SIZEOF_STRUCT(MENUITEMINFOW, cch) + #ifdef UNICODE + #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400W + #else + #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400A + #endif // !UNICODE +#endif // (WINVER >= 0x0500) + +class CMenuItemInfo : public MENUITEMINFO +{ +public: + CMenuItemInfo() + { + memset(this, 0, sizeof(MENUITEMINFO)); + cbSize = sizeof(MENUITEMINFO); +#if (WINVER >= 0x0500) + // adjust struct size if running on older version of Windows + if(AtlIsOldWindows()) + { + ATLASSERT(cbSize > MENUITEMINFO_SIZE_VERSION_400); // must be + cbSize = MENUITEMINFO_SIZE_VERSION_400; + } +#endif // (WINVER >= 0x0500) + } +}; + + +// forward declarations +template class CMenuT; +typedef CMenuT CMenuHandle; +typedef CMenuT CMenu; + + +template +class CMenuT +{ +public: +// Data members + HMENU m_hMenu; + +// Constructor/destructor/operators + CMenuT(HMENU hMenu = NULL) : m_hMenu(hMenu) + { } + + ~CMenuT() + { + if(t_bManaged && m_hMenu != NULL) + DestroyMenu(); + } + + CMenuT& operator =(HMENU hMenu) + { + Attach(hMenu); + return *this; + } + + void Attach(HMENU hMenuNew) + { + ATLASSERT(::IsMenu(hMenuNew)); + if(t_bManaged && m_hMenu != NULL && m_hMenu != hMenuNew) + ::DestroyMenu(m_hMenu); + m_hMenu = hMenuNew; + } + + HMENU Detach() + { + HMENU hMenu = m_hMenu; + m_hMenu = NULL; + return hMenu; + } + + operator HMENU() const { return m_hMenu; } + + bool IsNull() const { return (m_hMenu == NULL); } + + BOOL IsMenu() const + { + return ::IsMenu(m_hMenu); + } + +// Create/destroy methods + BOOL CreateMenu() + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::CreateMenu(); + return (m_hMenu != NULL) ? TRUE : FALSE; + } + + BOOL CreatePopupMenu() + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::CreatePopupMenu(); + return (m_hMenu != NULL) ? TRUE : FALSE; + } + + BOOL LoadMenu(ATL::_U_STRINGorID menu) + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); + return (m_hMenu != NULL) ? TRUE : FALSE; + } + +#ifndef _WIN32_WCE + BOOL LoadMenuIndirect(const void* lpMenuTemplate) + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::LoadMenuIndirect(lpMenuTemplate); + return (m_hMenu != NULL) ? TRUE : FALSE; + } +#endif // !_WIN32_WCE + + BOOL DestroyMenu() + { + if (m_hMenu == NULL) + return FALSE; + BOOL bRet = ::DestroyMenu(m_hMenu); + if(bRet) + m_hMenu = NULL; + return bRet; + } + +// Menu Operations + BOOL DeleteMenu(UINT nPosition, UINT nFlags) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::DeleteMenu(m_hMenu, nPosition, nFlags); + } + + BOOL TrackPopupMenu(UINT nFlags, int x, int y, HWND hWnd, LPCRECT lpRect = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); +#ifndef _WIN32_WCE +#if (WINVER >= 0x0500) + x = _FixTrackMenuPopupX(x, y); +#endif // !(WINVER >= 0x0500) + return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, hWnd, lpRect); +#else // CE specific + lpRect; + return ::TrackPopupMenuEx(m_hMenu, nFlags, x, y, hWnd, NULL); +#endif // _WIN32_WCE + } + + BOOL TrackPopupMenuEx(UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + x = _FixTrackMenuPopupX(x, y); +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + return ::TrackPopupMenuEx(m_hMenu, uFlags, x, y, hWnd, lptpm); + } + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + // helper that fixes popup menu X position when it's off-screen + static int _FixTrackMenuPopupX(int x, int y) + { + POINT pt = { x, y }; + HMONITOR hMonitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); + if(hMonitor == NULL) + { + HMONITOR hMonitorNear = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + if(hMonitorNear != NULL) + { + MONITORINFO mi = { 0 }; + mi.cbSize = sizeof(MONITORINFO); + if(::GetMonitorInfo(hMonitorNear, &mi) != FALSE) + { + if(x < mi.rcWork.left) + x = mi.rcWork.left; + else if(x > mi.rcWork.right) + x = mi.rcWork.right; + } + } + } + + return x; + } + + BOOL GetMenuInfo(LPMENUINFO lpMenuInfo) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuInfo(m_hMenu, lpMenuInfo); + } + + BOOL SetMenuInfo(LPCMENUINFO lpMenuInfo) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuInfo(m_hMenu, lpMenuInfo); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + +// Menu Item Operations + BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::AppendMenu(m_hMenu, nFlags, nIDNewItem, lpszNewItem); + } + + BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::AppendMenu(m_hMenu, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); + } + +#ifndef _WIN32_WCE + BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::AppendMenu(m_hMenu, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); + } + + BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::AppendMenu(m_hMenu, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); + } +#endif // !_WIN32_WCE + + UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck) + { + ATLASSERT(::IsMenu(m_hMenu)); + return (UINT)::CheckMenuItem(m_hMenu, nIDCheckItem, nCheck); + } + + UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::EnableMenuItem(m_hMenu, nIDEnableItem, nEnable); + } + +#ifndef _WIN32_WCE + BOOL HiliteMenuItem(HWND hWnd, UINT uIDHiliteItem, UINT uHilite) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::HiliteMenuItem(hWnd, m_hMenu, uIDHiliteItem, uHilite); + } + + int GetMenuItemCount() const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuItemCount(m_hMenu); + } + + UINT GetMenuItemID(int nPos) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuItemID(m_hMenu, nPos); + } + + UINT GetMenuState(UINT nID, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuState(m_hMenu, nID, nFlags); + } + + int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags); + } + + int GetMenuStringLen(UINT nIDItem, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags); + } + +#ifndef _ATL_NO_COM + BOOL GetMenuString(UINT nIDItem, BSTR& bstrText, UINT nFlags) const + { + USES_CONVERSION; + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(bstrText == NULL); + + int nLen = GetMenuStringLen(nIDItem, nFlags); + if(nLen == 0) + { + bstrText = ::SysAllocString(OLESTR("")); + return (bstrText != NULL) ? TRUE : FALSE; + } + + nLen++; // increment to include terminating NULL char + CTempBuffer buff; + LPTSTR lpszText = buff.Allocate(nLen); + if(lpszText == NULL) + return FALSE; + + if(!GetMenuString(nIDItem, lpszText, nLen, nFlags)) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpszText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#elif _ATL_VER >= 0x800 + int GetMenuItemCount() const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuItemCount(m_hMenu); + } + + UINT GetMenuItemID(int nPos) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuItemID(m_hMenu, nPos); + } + + UINT GetMenuState(UINT nID, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuState(m_hMenu, nID, nFlags); + } + + int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags); + } + + int GetMenuStringLen(UINT nIDItem, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags); + } +#endif // _ATL_VER >= 0x800 + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetMenuString(UINT nIDItem, _CSTRING_NS::CString& strText, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + + int nLen = GetMenuStringLen(nIDItem, nFlags); + if(nLen == 0) + return 0; + + nLen++; // increment to include terminating NULL char + LPTSTR lpstr = strText.GetBufferSetLength(nLen); + if(lpstr == NULL) + return 0; + int nRet = GetMenuString(nIDItem, lpstr, nLen, nFlags); + strText.ReleaseBuffer(); + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + CMenuHandle GetSubMenu(int nPos) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return CMenuHandle(::GetSubMenu(m_hMenu, nPos)); + } + + BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem); + } + + BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); + } + +#ifndef _WIN32_WCE + BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); + } + + BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); + } +#endif // !_WIN32_WCE + + BOOL RemoveMenu(UINT nPosition, UINT nFlags) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::RemoveMenu(m_hMenu, nPosition, nFlags); + } + +#ifndef _WIN32_WCE + BOOL SetMenuItemBitmaps(UINT nPosition, UINT nFlags, HBITMAP hBmpUnchecked, HBITMAP hBmpChecked) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuItemBitmaps(m_hMenu, nPosition, nFlags, hBmpUnchecked, hBmpChecked); + } +#endif // !_WIN32_WCE + + BOOL CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::CheckMenuRadioItem(m_hMenu, nIDFirst, nIDLast, nIDItem, nFlags); + } + + BOOL GetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return (BOOL)::GetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii); + } + + BOOL SetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) + { + ATLASSERT(::IsMenu(m_hMenu)); + return (BOOL)::SetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii); + } + +#ifndef _WIN32_WCE + BOOL InsertMenuItem(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) + { + ATLASSERT(::IsMenu(m_hMenu)); + return (BOOL)::InsertMenuItem(m_hMenu, uItem, bByPosition, lpmii); + } + + UINT GetMenuDefaultItem(BOOL bByPosition = FALSE, UINT uFlags = 0U) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuDefaultItem(m_hMenu, (UINT)bByPosition, uFlags); + } + + BOOL SetMenuDefaultItem(UINT uItem = (UINT)-1, BOOL bByPosition = FALSE) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuDefaultItem(m_hMenu, uItem, (UINT)bByPosition); + } + + BOOL GetMenuItemRect(HWND hWnd, UINT uItem, LPRECT lprcItem) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuItemRect(hWnd, m_hMenu, uItem, lprcItem); + } + + int MenuItemFromPoint(HWND hWnd, POINT point) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::MenuItemFromPoint(hWnd, m_hMenu, point); + } + +// Context Help Functions + BOOL SetMenuContextHelpId(DWORD dwContextHelpId) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId); + } + + DWORD GetMenuContextHelpId() const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuContextHelpId(m_hMenu); + } +#endif // !_WIN32_WCE +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAccelerator + +template +class CAcceleratorT +{ +public: + HACCEL m_hAccel; + +// Constructor/destructor/operators + CAcceleratorT(HACCEL hAccel = NULL) : m_hAccel(hAccel) + { } + + ~CAcceleratorT() + { + if(t_bManaged && m_hAccel != NULL) + ::DestroyAcceleratorTable(m_hAccel); + } + + CAcceleratorT& operator =(HACCEL hAccel) + { + Attach(hAccel); + return *this; + } + + void Attach(HACCEL hAccel) + { + if(t_bManaged && m_hAccel != NULL) + ::DestroyAcceleratorTable(m_hAccel); + m_hAccel = hAccel; + } + + HACCEL Detach() + { + HACCEL hAccel = m_hAccel; + m_hAccel = NULL; + return hAccel; + } + + operator HACCEL() const { return m_hAccel; } + + bool IsNull() const { return m_hAccel == NULL; } + +// Create/destroy methods + HACCEL LoadAccelerators(ATL::_U_STRINGorID accel) + { + ATLASSERT(m_hAccel == NULL); + m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), accel.m_lpstr); + return m_hAccel; + } + + HACCEL CreateAcceleratorTable(LPACCEL pAccel, int cEntries) + { + ATLASSERT(m_hAccel == NULL); + ATLASSERT(pAccel != NULL); + m_hAccel = ::CreateAcceleratorTable(pAccel, cEntries); + return m_hAccel; + } + + void DestroyObject() + { + if(m_hAccel != NULL) + { + ::DestroyAcceleratorTable(m_hAccel); + m_hAccel = NULL; + } + } + +// Operations +#ifndef _WIN32_WCE + int CopyAcceleratorTable(LPACCEL lpAccelDst, int cEntries) + { + ATLASSERT(m_hAccel != NULL); + ATLASSERT(lpAccelDst != NULL); + return ::CopyAcceleratorTable(m_hAccel, lpAccelDst, cEntries); + } + + int GetEntriesCount() const + { + ATLASSERT(m_hAccel != NULL); + return ::CopyAcceleratorTable(m_hAccel, NULL, 0); + } +#endif // !_WIN32_WCE + + BOOL TranslateAccelerator(HWND hWnd, LPMSG pMsg) + { + ATLASSERT(m_hAccel != NULL); + ATLASSERT(::IsWindow(hWnd)); + ATLASSERT(pMsg != NULL); + return ::TranslateAccelerator(hWnd, m_hAccel, pMsg); + } +}; + +typedef CAcceleratorT CAcceleratorHandle; +typedef CAcceleratorT CAccelerator; + + +/////////////////////////////////////////////////////////////////////////////// +// CIcon + +template +class CIconT +{ +public: + HICON m_hIcon; + +// Constructor/destructor/operators + CIconT(HICON hIcon = NULL) : m_hIcon(hIcon) + { } + + ~CIconT() + { + if(t_bManaged && m_hIcon != NULL) + ::DestroyIcon(m_hIcon); + } + + CIconT& operator =(HICON hIcon) + { + Attach(hIcon); + return *this; + } + + void Attach(HICON hIcon) + { + if(t_bManaged && m_hIcon != NULL) + ::DestroyIcon(m_hIcon); + m_hIcon = hIcon; + } + + HICON Detach() + { + HICON hIcon = m_hIcon; + m_hIcon = NULL; + return hIcon; + } + + operator HICON() const { return m_hIcon; } + + bool IsNull() const { return m_hIcon == NULL; } + +// Create/destroy methods + HICON LoadIcon(ATL::_U_STRINGorID icon) + { + ATLASSERT(m_hIcon == NULL); + m_hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); + return m_hIcon; + } + + HICON LoadIcon(ATL::_U_STRINGorID icon, int cxDesired, int cyDesired, UINT fuLoad = 0) + { + ATLASSERT(m_hIcon == NULL); + m_hIcon = (HICON) ::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); + return m_hIcon; + } + +#ifndef _WIN32_WCE + HICON LoadOEMIcon(LPCTSTR lpstrIconName) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(IsOEMIcon(lpstrIconName)); + m_hIcon = ::LoadIcon(NULL, lpstrIconName); + return m_hIcon; + } + + HICON CreateIcon(int nWidth, int nHeight, BYTE cPlanes, BYTE cBitsPixel, CONST BYTE* lpbANDbits, CONST BYTE *lpbXORbits) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(lpbANDbits != NULL); + ATLASSERT(lpbXORbits != NULL); + m_hIcon = ::CreateIcon(ModuleHelper::GetResourceInstance(), nWidth, nHeight, cPlanes, cBitsPixel, lpbANDbits, lpbXORbits); + return m_hIcon; + } + + HICON CreateIconFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(pBits != NULL); + m_hIcon = ::CreateIconFromResource(pBits, dwResSize, TRUE, dwVersion); + return m_hIcon; + } + + HICON CreateIconFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(pbBits != NULL); + ATLASSERT(cbBits > 0); + m_hIcon = ::CreateIconFromResourceEx(pbBits, cbBits, TRUE, dwVersion, cxDesired, cyDesired, uFlags); + return m_hIcon; + } +#endif // !_WIN32_WCE + + HICON CreateIconIndirect(PICONINFO pIconInfo) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(pIconInfo != NULL); + m_hIcon = ::CreateIconIndirect(pIconInfo); + return m_hIcon; + } + +#ifndef _WIN32_WCE + HICON ExtractIcon(LPCTSTR lpszExeFileName, UINT nIconIndex) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(lpszExeFileName != NULL); + m_hIcon = ::ExtractIcon(ModuleHelper::GetModuleInstance(), lpszExeFileName, nIconIndex); + return m_hIcon; + } + + HICON ExtractAssociatedIcon(HINSTANCE hInst, LPTSTR lpIconPath, LPWORD lpiIcon) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(lpIconPath != NULL); + ATLASSERT(lpiIcon != NULL); + m_hIcon = ::ExtractAssociatedIcon(hInst, lpIconPath, lpiIcon); + return m_hIcon; + } +#endif // !_WIN32_WCE + + BOOL DestroyIcon() + { + ATLASSERT(m_hIcon != NULL); + BOOL bRet = ::DestroyIcon(m_hIcon); + if(bRet != FALSE) + m_hIcon = NULL; + return bRet; + } + +// Operations +#ifndef _WIN32_WCE + HICON CopyIcon() + { + ATLASSERT(m_hIcon != NULL); + return ::CopyIcon(m_hIcon); + } + + HICON DuplicateIcon() + { + ATLASSERT(m_hIcon != NULL); + return ::DuplicateIcon(NULL, m_hIcon); + } +#endif // !_WIN32_WCE + + BOOL DrawIcon(HDC hDC, int x, int y) + { + ATLASSERT(m_hIcon != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(hDC, x, y, m_hIcon); +#else // CE specific + return ::DrawIconEx(hDC, x, y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIcon(HDC hDC, POINT pt) + { + ATLASSERT(m_hIcon != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(hDC, pt.x, pt.y, m_hIcon); +#else // CE specific + return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIconEx(HDC hDC, int x, int y, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hIcon != NULL); + return ::DrawIconEx(hDC, x, y, m_hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + + BOOL DrawIconEx(HDC hDC, POINT pt, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hIcon != NULL); + return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + +#ifndef _WIN32_WCE + BOOL GetIconInfo(PICONINFO pIconInfo) const + { + ATLASSERT(m_hIcon != NULL); + ATLASSERT(pIconInfo != NULL); + return ::GetIconInfo(m_hIcon, pIconInfo); + } + +#if (_WIN32_WINNT >= 0x0600) + BOOL GetIconInfoEx(PICONINFOEX pIconInfo) const + { + ATLASSERT(m_hIcon != NULL); + ATLASSERT(pIconInfo != NULL); + return ::GetIconInfoEx(m_hIcon, pIconInfo); + } +#endif // (_WIN32_WINNT >= 0x0600) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + HRESULT LoadIconMetric(ATL::_U_STRINGorID icon, int lims) + { + ATLASSERT(m_hIcon == NULL); + USES_CONVERSION; + return ::LoadIconMetric(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), lims, &m_hIcon); + } + + HRESULT LoadIconWithScaleDown(ATL::_U_STRINGorID icon, int cx, int cy) + { + ATLASSERT(m_hIcon == NULL); + USES_CONVERSION; + return ::LoadIconWithScaleDown(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), cx, cy, &m_hIcon); + } + + HRESULT LoadOEMIconMetric(LPCTSTR lpstrIconName, int lims) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(IsOEMIcon(lpstrIconName)); + return ::LoadIconMetric(NULL, (LPCWSTR)lpstrIconName, lims, &m_hIcon); + } + + HRESULT LoadOEMIconWithScaleDown(LPCTSTR lpstrIconName, int cx, int cy) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(IsOEMIcon(lpstrIconName)); + USES_CONVERSION; + return ::LoadIconWithScaleDown(NULL, (LPCWSTR)lpstrIconName, cx, cy, &m_hIcon); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) +#endif // !_WIN32_WCE + + // Helper +#ifndef _WIN32_WCE + static bool IsOEMIcon(LPCTSTR lpstrIconName) + { +#if (WINVER >= 0x0600) + return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION || + lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO || + lpstrIconName == IDI_SHIELD); +#else // !(WINVER >= 0x0600) + return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION || + lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO); +#endif // !(WINVER >= 0x0600) + } +#endif // !_WIN32_WCE +}; + +typedef CIconT CIconHandle; +typedef CIconT CIcon; + + +/////////////////////////////////////////////////////////////////////////////// +// CCursor + +// protect template member from a winuser.h macro +#ifdef CopyCursor + #undef CopyCursor +#endif + +template +class CCursorT +{ +public: + HCURSOR m_hCursor; + +// Constructor/destructor/operators + CCursorT(HCURSOR hCursor = NULL) : m_hCursor(hCursor) + { } + + ~CCursorT() + { + if(t_bManaged && m_hCursor != NULL) + DestroyCursor(); + } + + CCursorT& operator =(HCURSOR hCursor) + { + Attach(hCursor); + return *this; + } + + void Attach(HCURSOR hCursor) + { + if(t_bManaged && m_hCursor != NULL) + DestroyCursor(); + m_hCursor = hCursor; + } + + HCURSOR Detach() + { + HCURSOR hCursor = m_hCursor; + m_hCursor = NULL; + return hCursor; + } + + operator HCURSOR() const { return m_hCursor; } + + bool IsNull() const { return m_hCursor == NULL; } + +// Create/destroy methods + HCURSOR LoadCursor(ATL::_U_STRINGorID cursor) + { + ATLASSERT(m_hCursor == NULL); + m_hCursor = ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr); + return m_hCursor; + } + + HCURSOR LoadSysCursor(LPCTSTR lpstrCursorName) + { + ATLASSERT(m_hCursor == NULL); +#if (WINVER >= 0x0500) + ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT || + lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE || + lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW || + lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL || + lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP || + lpstrCursorName == IDC_HAND); +#else // !(WINVER >= 0x0500) + ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT || + lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE || + lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW || + lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL || + lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP); +#endif // !(WINVER >= 0x0500) + m_hCursor = ::LoadCursor(NULL, lpstrCursorName); + return m_hCursor; + } + + // deprecated + HCURSOR LoadOEMCursor(LPCTSTR lpstrCursorName) + { + return LoadSysCursor(lpstrCursorName); + } + + HCURSOR LoadCursor(ATL::_U_STRINGorID cursor, int cxDesired, int cyDesired, UINT fuLoad = 0) + { + ATLASSERT(m_hCursor == NULL); + m_hCursor = (HCURSOR) ::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); + return m_hCursor; + } + +#ifndef _WIN32_WCE + HCURSOR LoadCursorFromFile(LPCTSTR pstrFilename) + { + ATLASSERT(m_hCursor == NULL); + ATLASSERT(pstrFilename != NULL); + m_hCursor = ::LoadCursorFromFile(pstrFilename); + return m_hCursor; + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + HCURSOR CreateCursor(int xHotSpot, int yHotSpot, int nWidth, int nHeight, CONST VOID *pvANDPlane, CONST VOID *pvXORPlane) + { + ATLASSERT(m_hCursor == NULL); + m_hCursor = ::CreateCursor(ModuleHelper::GetResourceInstance(), xHotSpot, yHotSpot, nWidth, nHeight, pvANDPlane, pvXORPlane); + return m_hCursor; + } +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + +#ifndef _WIN32_WCE + HCURSOR CreateCursorFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000) + { + ATLASSERT(m_hCursor == NULL); + ATLASSERT(pBits != NULL); + m_hCursor = (HCURSOR)::CreateIconFromResource(pBits, dwResSize, FALSE, dwVersion); + return m_hCursor; + } + + HCURSOR CreateCursorFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR) + { + ATLASSERT(m_hCursor == NULL); + ATLASSERT(pbBits != NULL); + ATLASSERT(cbBits > 0); + m_hCursor = (HCURSOR)::CreateIconFromResourceEx(pbBits, cbBits, FALSE, dwVersion, cxDesired, cyDesired, uFlags); + return m_hCursor; + } +#endif // !_WIN32_WCE + + BOOL DestroyCursor() + { + ATLASSERT(m_hCursor != NULL); +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + BOOL bRet = ::DestroyCursor(m_hCursor); + if(bRet != FALSE) + m_hCursor = NULL; + return bRet; +#else // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))) + ATLTRACE2(atlTraceUI, 0, _T("Warning: This version of Windows CE does not have ::DestroyCursor()\n")); + return FALSE; +#endif // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))) + } + +// Operations +#ifndef _WIN32_WCE + HCURSOR CopyCursor() + { + ATLASSERT(m_hCursor != NULL); + return (HCURSOR)::CopyIcon((HICON)m_hCursor); + } +#endif // !_WIN32_WCE + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + BOOL GetCursorInfo(LPCURSORINFO pCursorInfo) + { + ATLASSERT(m_hCursor != NULL); + ATLASSERT(pCursorInfo != NULL); + return ::GetCursorInfo(pCursorInfo); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CCursorT CCursorHandle; +typedef CCursorT CCursor; + + +/////////////////////////////////////////////////////////////////////////////// +// CResource - Wraps a generic Windows resource. +// Use it with custom resource types other than the +// standard RT_CURSOR, RT_BITMAP, etc. + +class CResource +{ +public: + HGLOBAL m_hGlobal; + HRSRC m_hResource; + +// Constructor/destructor + CResource() : m_hGlobal(NULL), m_hResource(NULL) + { } + + ~CResource() + { + Release(); + } + +// Load methods + bool Load(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID) + { + ATLASSERT(m_hResource == NULL); + ATLASSERT(m_hGlobal == NULL); + + m_hResource = ::FindResource(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr); + if(m_hResource == NULL) + return false; + + m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource); + if(m_hGlobal == NULL) + { + m_hResource = NULL; + return false; + } + + return true; + } + +#ifndef _WIN32_WCE + bool LoadEx(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID, WORD wLanguage) + { + ATLASSERT(m_hResource == NULL); + ATLASSERT(m_hGlobal == NULL); + + m_hResource = ::FindResourceEx(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr, wLanguage); + if(m_hResource == NULL) + return false; + + m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource); + if(m_hGlobal == NULL) + { + m_hResource = NULL; + return false; + } + + return true; + } +#endif // !_WIN32_WCE + +// Misc. operations + DWORD GetSize() const + { + ATLASSERT(m_hResource != NULL); + return ::SizeofResource(ModuleHelper::GetResourceInstance(), m_hResource); + } + + LPVOID Lock() + { + ATLASSERT(m_hResource != NULL); + ATLASSERT(m_hGlobal != NULL); + LPVOID pVoid = ::LockResource(m_hGlobal); + ATLASSERT(pVoid != NULL); + return pVoid; + } + + void Release() + { + if(m_hGlobal != NULL) + { + FreeResource(m_hGlobal); + m_hGlobal = NULL; + m_hResource = NULL; + } + } +}; + +}; // namespace WTL + +#endif // __ATLUSER_H__ diff --git a/ext/CrashServer/external/WTL/Include/atlwinx.h b/ext/CrashServer/external/WTL/Include/atlwinx.h new file mode 100644 index 000000000..2d193f5fa --- /dev/null +++ b/ext/CrashServer/external/WTL/Include/atlwinx.h @@ -0,0 +1,529 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLWINX_H__ +#define __ATLWINX_H__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLAPP_H__ + #error atlwinx.h requires atlapp.h to be included first +#endif + +#if (_ATL_VER >= 0x0700) + #include +#endif // (_ATL_VER >= 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// _U_RECT +// _U_MENUorID +// _U_STRINGorID + + +/////////////////////////////////////////////////////////////////////////////// +// Command Chaining Macros + +#define CHAIN_COMMANDS(theChainClass) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP(theChainClass) + +#define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) + +#define CHAIN_COMMANDS_MEMBER(theChainMember) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP_MEMBER(theChainMember) + +#define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) + + +/////////////////////////////////////////////////////////////////////////////// +// Macros for parent message map to selectively reflect control messages + +// NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot +// (and overridden in 2 cases - CContainedWindowT and CAxHostWindow) +// Since we can't modify ATL, we'll provide the needed additions +// in a separate function (that is not a member of CWindowImplRoot) + +namespace WTL +{ + +inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled, + UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL) +{ + if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg)) + { + // The notification message doesn't match the filter. + bHandled = FALSE; + return 1; + } + + HWND hWndChild = NULL; + UINT_PTR idFrom = 0; + + switch(uMsg) + { + case WM_COMMAND: + if(lParam != NULL) // not from a menu + { + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)LOWORD(wParam); + } + break; + case WM_NOTIFY: + hWndChild = ((LPNMHDR)lParam)->hwndFrom; + idFrom = ((LPNMHDR)lParam)->idFrom; + break; +#ifndef _WIN32_WCE + case WM_PARENTNOTIFY: + switch(LOWORD(wParam)) + { + case WM_CREATE: + case WM_DESTROY: + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)HIWORD(wParam); + break; + default: + hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam)); + idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); + break; + } + break; +#endif // !_WIN32_WCE + case WM_DRAWITEM: + if(wParam) // not from a menu + { + hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem; + idFrom = (UINT_PTR)wParam; + } + break; + case WM_MEASUREITEM: + if(wParam) // not from a menu + { + hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID); + idFrom = (UINT_PTR)wParam; + } + break; + case WM_COMPAREITEM: + if(wParam) // not from a menu + { + hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem; + idFrom = (UINT_PTR)wParam; + } + break; + case WM_DELETEITEM: + if(wParam) // not from a menu + { + hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem; + idFrom = (UINT_PTR)wParam; + } + break; + case WM_VKEYTOITEM: + case WM_CHARTOITEM: + case WM_HSCROLL: + case WM_VSCROLL: + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); + break; + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); + break; + default: + break; + } + + if((hWndChild == NULL) || + ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild))) + { + // Either hWndChild isn't valid, or + // hWndChild doesn't match the filter. + bHandled = FALSE; + return 1; + } + + if((idFromFilter != 0) && (idFromFilter != idFrom)) + { + // The dialog control id doesn't match the filter. + bHandled = FALSE; + return 1; + } + + ATLASSERT(::IsWindow(hWndChild)); + LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam); + if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) + { + // Try to prevent problems with WM_CTLCOLOR* messages when + // the message wasn't really handled + bHandled = FALSE; + } + + return lResult; +} + +}; // namespace WTL + +// Try to prevent problems with WM_CTLCOLOR* messages when +// the message wasn't really handled +#define REFLECT_NOTIFICATIONS_EX() \ +{ \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \ + bHandled = FALSE; \ + if(bHandled) \ + return TRUE; \ +} + +#define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND(id, code) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_ID(id) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_CODE(code) \ + if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_RANGE(idFirst, idLast) \ + if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \ + if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY(id, cd) \ + if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_ID(id) \ + if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_CODE(cd) \ + if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_RANGE(idFirst, idLast) \ + if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \ + if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + + +/////////////////////////////////////////////////////////////////////////////// +// Reflected message handler macros for message maps (for ATL 3.0) + +#if (_ATL_VER < 0x0700) + +#define REFLECTED_COMMAND_HANDLER(id, code, func) \ + if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_ID_HANDLER(id, func) \ + if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_CODE_HANDLER(code, func) \ + if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \ + if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \ + if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_HANDLER(id, cd, func) \ + if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_ID_HANDLER(id, func) \ + if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \ + if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \ + if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \ + if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#endif // (_ATL_VER < 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// Dual argument helper classes (for ATL 3.0) + +#if (_ATL_VER < 0x0700) + +namespace ATL +{ + +class _U_RECT +{ +public: + _U_RECT(LPRECT lpRect) : m_lpRect(lpRect) + { } + _U_RECT(RECT& rc) : m_lpRect(&rc) + { } + LPRECT m_lpRect; +}; + +class _U_MENUorID +{ +public: + _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu) + { } + _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID)) + { } + HMENU m_hMenu; +}; + +class _U_STRINGorID +{ +public: + _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) + { } + _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID)) + { } + LPCTSTR m_lpstr; +}; + +}; // namespace ATL + +#endif // (_ATL_VER < 0x0700) + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// Forward notifications support for message maps (for ATL 3.0) + +#if (_ATL_VER < 0x0700) + +// forward notifications support +#define FORWARD_NOTIFICATIONS() \ + { \ + bHandled = TRUE; \ + lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + LRESULT lResult = 0; + switch(uMsg) + { + case WM_COMMAND: + case WM_NOTIFY: +#ifndef _WIN32_WCE + case WM_PARENTNOTIFY: +#endif // !_WIN32_WCE + case WM_DRAWITEM: + case WM_MEASUREITEM: + case WM_COMPAREITEM: + case WM_DELETEITEM: + case WM_VKEYTOITEM: + case WM_CHARTOITEM: + case WM_HSCROLL: + case WM_VSCROLL: + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: + lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam); + break; + default: + bHandled = FALSE; + break; + } + return lResult; +} + +#endif // (_ATL_VER < 0x0700) + +}; // namespace WTL + +#endif // __ATLWINX_H__ diff --git a/ext/CrashServer/external/gsoap-win32-2.8.0/mod_gsoap/gsoap_win/wininet/gsoapWinInet.h b/ext/CrashServer/external/gsoap-win32-2.8.0/mod_gsoap/gsoap_win/wininet/gsoapWinInet.h new file mode 100644 index 000000000..1f5b42878 --- /dev/null +++ b/ext/CrashServer/external/gsoap-win32-2.8.0/mod_gsoap/gsoap_win/wininet/gsoapWinInet.h @@ -0,0 +1,196 @@ +/* +=============================================================================== +GSOAP WININET PLUGIN +------------------------------------------------------------------------------- + +Allow gsoap clients (not servers) to direct all communications through the +WinInet API. This automatically provides all of the proxy and authentication +features supported by the control panel 'Internet Options' dialog to the +client. As these options are shared by IE, this means that "if IE works, +gsoap works." + +Project Home: http://code.google.com/p/gsoapwininet/ + +------------------------------------------------------------------------------- +Features +------------------------------------------------------------------------------- + + + gsoap plugin - extremely easy to use + + complete support for: + - HTTP/1.0 and HTTP/1.1 + - HTTPS (no extra libraries are required) + - HTTP authentication + - Proxy servers (simple, automatic discovery, etc) + - Proxy authentication (basic, NTLM, etc) + + authentication prompts and HTTPS warnings (e.g. invalid HTTPS CA) + can be resolved by the user via standard system dialog boxes. + + message size is limited only by available memory + + connect, receive and send timeouts are used + + supports all SOAP_IO types (see limitations) + + written completely in C, can be used in C, C++, and MFC projects + without modification (anywhere that gsoap is used) + + can be used in both MBCS and UNICODE projects + + compiles cleanly at warning level 4 (if gsoap uses SOAP_SOCKET + for the definition of sockets instead of int, it will also + compile without win64 warnings). + + all debug trace goes to the gsoap TEST.log file + + supports multiple threads (all plugin data is stored in the + soap structure - no static variables) + +------------------------------------------------------------------------------- +Limitations +------------------------------------------------------------------------------- + - DIME attachments are not supported + - may internally buffer the entire outgoing message before sending + (if the serialized message is larger then SOAP_BUFLEN, or if + SOAP_IO_CHUNK mode is being used then the entire message will + be buffered) + +------------------------------------------------------------------------------- +Usage +------------------------------------------------------------------------------- + +Add the gsoapWinInet2.h and gsoapWinInet2.cpp files to your project (if you +have a C project, rename gsoapWinInet2.cpp to .c and use it as is). Ensure +that you turn off precompiled headers for the .cpp file. + +In your source, just after calling soap_init(), register this plugin with +soap_register_plugin( soap, wininet_plugin ). + +For example: + struct soap soap; + soap_init( &soap ); + soap_register_plugin( &soap, wininet_plugin ); + soap.connect_timeout = 5; // this will be used by wininet too + ... + soap_done(&soap); + +------------------------------------------------------------------------------- +Notes +------------------------------------------------------------------------------- + +For extra control, you may also register this plugin using the +soap_register_plugin_arg() function, and supply as the argument flags which +you want to be passed to HttpOpenRequest. + +For example: + struct soap soap; + soap_init( &soap ); + soap_register_plugin_arg( &soap, wininet_plugin, + (void*) INTERNET_FLAG_IGNORE_CERT_CN_INVALID ); + +See the MSDN documentation on HttpOpenRequest for details of available flags. +The header file is required for the definitions of the flags. +Some flags which may be useful are: + +INTERNET_FLAG_KEEP_CONNECTION + + Uses keep-alive semantics, if available, for the connection. + This flag is required for Microsoft Network (MSN), NT LAN + Manager (NTLM), and other types of authentication. + ++ Note that this flag is used automatically when soap.omode + has the SOAP_IO_KEEPALIVE flag set. ++ + +INTERNET_FLAG_IGNORE_CERT_CN_INVALID + + Disables Microsoft Win32 Internet function checking of SSL/PCT- + based certificates that are returned from the server against + the host name given in the request. + +INTERNET_FLAG_IGNORE_CERT_DATE_INVALID + + Disables Win32 Internet function checking of SSL/PCT-based + certificates for proper validity dates. + +This plugin uses the following callback functions and is not compatible +with any other plugin that uses these functions. + + soap->fopen + soap->fposthdr + soap->fsend + soap->frecv + soap->fclose + +If there are errors in sending the HTTP request which would cause a dialog +box to be displayed in IE (for instance, invalid certificates on an HTTPS +connection), then a dialog will also be displayed by this library. At the +moment is is not possible to disable the UI. If you wish to remove the UI +then you will need to hack the source to remove the dialog box and resolve the +errors programmatically, or supply the appropriate flags in +soap_register_plugin_arg() to disable the unwanted warnings. + +Because messages are buffered internally to gsoapWinInet2 plugin it is +recommended that the SOAP_IO_STORE flag is not used otherwise the message may +be buffered twice on every send. Use the default flag SOAP_IO_BUFFER, +or SOAP_IO_FLUSH. + +------------------------------------------------------------------------------- +License +------------------------------------------------------------------------------- + +The licence text below is the boilerplate "MIT Licence" used from: +http://www.opensource.org/licenses/mit-license.php + +Copyright (c) 2009, Brodie Thiesfield + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------------------------------------------------------------------------------- +Developers +------------------------------------------------------------------------------- + +26 May 2003: Jack Kustanowitz (jackk@atomica.com) +Original version + +29 September 2003: Brodie Thiesfield (code@jellycan.com) +Rewritten as C plugin for gsoap. Bugs fixed and features added. + +14 January 2004: Brodie Thiesfield (code@jellycan.com) +Bug fix. + +17 March 2009: Brodie Thiesfield (code@jellycan.com) +Clean up and re-release. +*/ + +#ifndef INCLUDED_gsoapWinInet2_h +#define INCLUDED_gsoapWinInet2_h + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + rseFalse = 0, + rseTrue, + rseDisplayDlg +} wininet_rseReturn; + +typedef wininet_rseReturn(*wininet_rse_callback)(HINTERNET a_hHttpRequest, DWORD a_dwErrorCode); + +extern void wininet_set_rse_callback(struct soap *a_pSoap, wininet_rse_callback a_pRseCallback); + +extern int wininet_plugin(struct soap *a_pSoap, struct soap_plugin *a_pPluginData, void *a_pUnused); + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDED_gsoapWinInet2_h diff --git a/ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.cpp b/ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.cpp new file mode 100644 index 000000000..f01d0695b --- /dev/null +++ b/ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.cpp @@ -0,0 +1,15822 @@ +/* + stdsoap2.c[pp] 2.8.0 + + gSOAP runtime engine + +gSOAP XML Web services tools +Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc., All Rights Reserved. +This part of the software is released under ONE of the following licenses: +GPL, or the gSOAP public license, or Genivia's license for commercial use. +-------------------------------------------------------------------------------- +Contributors: + +Wind River Systems Inc., for the following additions under gSOAP public license: + - vxWorks compatible +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(the "License"); you may not use this file except in compliance with the +License. You may obtain a copy of the License at +http://www.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org + +This program is released under the GPL with the additional exemption that +compiling, linking, and/or using OpenSSL is allowed. +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- + +Installation note: + +Win32 build needs winsock.dll (Visual C++ "wsock32.lib") +To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link" +tab (the project file needs to be selected in the file view) and add +"wsock32.lib" to the "Object/library modules" entry + +On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with +-fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack +when locally allocated data exceeds 64K. + +*/ + +#ifdef AS400 +# pragma convert(819) /* EBCDIC to ASCII */ +#endif + +#include "stdsoap2.h" + +#ifdef __BORLANDC__ +# pragma warn -8060 +#else +# ifdef WIN32 +# ifdef UNDER_CE +# pragma comment(lib, "winsock.lib") +# else +# pragma comment(lib, "wsock32.lib") +# endif +# pragma warning(disable : 4996) /* disable deprecation warnings */ +# endif +#endif + +#ifdef __cplusplus +SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.8.0 2010-09-20 00:00:00 GMT") +extern "C" { +#else +SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.8.0 2010-09-20 00:00:00 GMT") +#endif + +/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */ +#ifndef SOAP_UNKNOWN_CHAR +#define SOAP_UNKNOWN_CHAR (127) +#endif + +/* EOF=-1 */ +#define SOAP_LT (soap_wchar)(-2) /* XML character '<' */ +#define SOAP_TT (soap_wchar)(-3) /* XML character '' */ +#define SOAP_QT (soap_wchar)(-5) /* XML character '"' */ +#define SOAP_AP (soap_wchar)(-6) /* XML character ''' */ + +#define soap_blank(c) ((c) >= 0 && (c) <= 32) +#define soap_notblank(c) ((c) > 32) + +#if defined(WIN32) && !defined(UNDER_CE) +#define soap_hash_ptr(p) ((PtrToUlong(p) >> 3) & (SOAP_PTRHASH - 1)) +#else +#define soap_hash_ptr(p) ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1))) +#endif + +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) +static void soap_init_logs(struct soap*); +#endif +#ifdef SOAP_DEBUG +static void soap_close_logfile(struct soap*, int); +static void soap_set_logfile(struct soap*, int, const char*); +#endif + +#ifdef SOAP_MEM_DEBUG +static void soap_init_mht(struct soap*); +static void soap_free_mht(struct soap*); +static void soap_track_unlink(struct soap*, const void*); +#endif + +#ifndef PALM_2 +static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int); +static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*); +static int soap_getattrval(struct soap*, char*, size_t, soap_wchar); +#endif + +#ifndef PALM_1 +static void soap_free_ns(struct soap *soap); +static soap_wchar soap_char(struct soap*); +static soap_wchar soap_get_pi(struct soap*); +static int soap_isxdigit(int); +static void *fplugin(struct soap*, const char*); +static size_t soap_count_attachments(struct soap *soap); +static int soap_try_connect_command(struct soap*, int http_command, const char *endpoint, const char *action); +#ifndef WITH_NOIDREF +static void soap_update_ptrs(struct soap*, char*, char*, char*, char*); +static int soap_has_copies(struct soap*, const char*, const char*); +static void soap_init_iht(struct soap*); +static void soap_free_iht(struct soap*); +static void soap_init_pht(struct soap*); +static void soap_free_pht(struct soap*); +#endif +#endif + +#ifndef WITH_LEAN +static const char *soap_set_validation_fault(struct soap*, const char*, const char*); +static int soap_isnumeric(struct soap*, const char*); +static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized); +static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n); +#endif + +#ifndef WITH_LEANER +#ifndef PALM_1 +static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t); +static int soap_putdimefield(struct soap*, const char*, size_t); +static char *soap_getdimefield(struct soap*, size_t); +static void soap_select_mime_boundary(struct soap*); +static int soap_valid_mime_boundary(struct soap*); +static void soap_resolve_attachment(struct soap*, struct soap_multipart*); +#endif +#endif + +#ifdef WITH_GZIP +static int soap_getgziphdr(struct soap*); +#endif + +#ifdef WITH_OPENSSL +# ifndef SOAP_SSL_RSA_BITS +# define SOAP_SSL_RSA_BITS 2048 +# endif +static int soap_ssl_init_done = 0; +static int ssl_auth_init(struct soap*); +static int ssl_verify_callback(int, X509_STORE_CTX*); +static int ssl_verify_callback_allow_expired_certificate(int, X509_STORE_CTX*); +static int ssl_password(char*, int, int, void *); +#endif + +#ifdef WITH_GNUTLS +# ifndef SOAP_SSL_RSA_BITS +# define SOAP_SSL_RSA_BITS 2048 +# endif +static int soap_ssl_init_done = 0; +static const char *ssl_verify(struct soap *soap, const char *host); +# if defined(HAVE_PTHREAD_H) +# include + /* make GNUTLS thread safe with pthreads */ + GCRY_THREAD_OPTION_PTHREAD_IMPL; +# elif defined(HAVE_PTH_H) + #include + /* make GNUTLS thread safe with PTH */ + GCRY_THREAD_OPTION_PTH_IMPL; +# endif +#endif + +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +static const char *soap_decode(char*, size_t, const char*, const char*); +#endif +#endif + +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static soap_wchar soap_getchunkchar(struct soap*); +static const char *http_error(struct soap*, int); +static int http_put(struct soap*); +static int http_get(struct soap*); +static int http_405(struct soap*); +static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t); +static int http_send_header(struct soap*, const char*); +static int http_post_header(struct soap*, const char*, const char*); +static int http_response(struct soap*, int, size_t); +static int http_parse(struct soap*); +static int http_parse_header(struct soap*, const char*, const char*); +#endif +#endif + +#ifndef WITH_NOIO + +#ifndef PALM_1 +static int fsend(struct soap*, const char*, size_t); +static size_t frecv(struct soap*, char*, size_t); +static int tcp_init(struct soap*); +static const char *tcp_error(struct soap*); +#ifndef WITH_IPV6 +static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr); +#endif +static SOAP_SOCKET tcp_connect(struct soap*, const char *endpoint, const char *host, int port); +static SOAP_SOCKET tcp_accept(struct soap*, SOAP_SOCKET, struct sockaddr*, int*); +static int tcp_select(struct soap*, SOAP_SOCKET, int, int); +static int tcp_disconnect(struct soap*); +static int tcp_closesocket(struct soap*, SOAP_SOCKET); +static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int); +static const char *soap_strerror(struct soap*); +#endif + +#define SOAP_TCP_SELECT_RCV 0x1 +#define SOAP_TCP_SELECT_SND 0x2 +#define SOAP_TCP_SELECT_ERR 0x4 +#define SOAP_TCP_SELECT_ALL 0x7 + +#if defined(WIN32) + #define SOAP_SOCKBLOCK(fd) \ + { u_long blocking = 0; \ + ioctlsocket(fd, FIONBIO, &blocking); \ + } + #define SOAP_SOCKNONBLOCK(fd) \ + { u_long nonblocking = 1; \ + ioctlsocket(fd, FIONBIO, &nonblocking); \ + } +#elif defined(VXWORKS) + #define SOAP_SOCKBLOCK(fd) \ + { u_long blocking = 0; \ + ioctl(fd, FIONBIO, (int)(&blocking)); \ + } + #define SOAP_SOCKNONBLOCK(fd) \ + { u_long nonblocking = 1; \ + ioctl(fd, FIONBIO, (int)(&nonblocking)); \ + } +#elif defined(PALM) + #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)&~O_NONBLOCK); + #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK); +#elif defined(SYMBIAN) + #define SOAP_SOCKBLOCK(fd) \ + { long blocking = 0; \ + ioctl(fd, 0/*FIONBIO*/, &blocking); \ + } + #define SOAP_SOCKNONBLOCK(fd) \ + { long nonblocking = 1; \ + ioctl(fd, 0/*FIONBIO*/, &nonblocking); \ + } +#else + #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK); + #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK); +#endif + +#endif + +#if defined(PALM) && !defined(PALM_2) +unsigned short errno; +#endif + +#ifndef PALM_1 +static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/"; +static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/"; +static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope"; +static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding"; +static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc"; +#endif + +#ifndef PALM_1 +const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF}; +static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char soap_base64i[81] = "\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63"; +#endif + +#ifndef WITH_LEAN +static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t"; +/* Alternative indentation form for SOAP_XML_INDENT: +static const char soap_indent[21] = "\n "; +*/ +#endif + +#ifndef SOAP_CANARY +# define SOAP_CANARY (0xC0DE) +#endif + +static const char soap_padding[4] = "\0\0\0"; +#define SOAP_STR_PADDING (soap_padding) +#define SOAP_STR_EOS (soap_padding) +#define SOAP_NON_NULL (soap_padding) + +#ifndef WITH_LEAN +static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */ +{ { 160, "nbsp" }, + { 161, "iexcl" }, + { 162, "cent" }, + { 163, "pound" }, + { 164, "curren" }, + { 165, "yen" }, + { 166, "brvbar" }, + { 167, "sect" }, + { 168, "uml" }, + { 169, "copy" }, + { 170, "ordf" }, + { 171, "laquo" }, + { 172, "not" }, + { 173, "shy" }, + { 174, "reg" }, + { 175, "macr" }, + { 176, "deg" }, + { 177, "plusmn" }, + { 178, "sup2" }, + { 179, "sup3" }, + { 180, "acute" }, + { 181, "micro" }, + { 182, "para" }, + { 183, "middot" }, + { 184, "cedil" }, + { 185, "sup1" }, + { 186, "ordm" }, + { 187, "raquo" }, + { 188, "frac14" }, + { 189, "frac12" }, + { 190, "frac34" }, + { 191, "iquest" }, + { 192, "Agrave" }, + { 193, "Aacute" }, + { 194, "Acirc" }, + { 195, "Atilde" }, + { 196, "Auml" }, + { 197, "Aring" }, + { 198, "AElig" }, + { 199, "Ccedil" }, + { 200, "Egrave" }, + { 201, "Eacute" }, + { 202, "Ecirc" }, + { 203, "Euml" }, + { 204, "Igrave" }, + { 205, "Iacute" }, + { 206, "Icirc" }, + { 207, "Iuml" }, + { 208, "ETH" }, + { 209, "Ntilde" }, + { 210, "Ograve" }, + { 211, "Oacute" }, + { 212, "Ocirc" }, + { 213, "Otilde" }, + { 214, "Ouml" }, + { 215, "times" }, + { 216, "Oslash" }, + { 217, "Ugrave" }, + { 218, "Uacute" }, + { 219, "Ucirc" }, + { 220, "Uuml" }, + { 221, "Yacute" }, + { 222, "THORN" }, + { 223, "szlig" }, + { 224, "agrave" }, + { 225, "aacute" }, + { 226, "acirc" }, + { 227, "atilde" }, + { 228, "auml" }, + { 229, "aring" }, + { 230, "aelig" }, + { 231, "ccedil" }, + { 232, "egrave" }, + { 233, "eacute" }, + { 234, "ecirc" }, + { 235, "euml" }, + { 236, "igrave" }, + { 237, "iacute" }, + { 238, "icirc" }, + { 239, "iuml" }, + { 240, "eth" }, + { 241, "ntilde" }, + { 242, "ograve" }, + { 243, "oacute" }, + { 244, "ocirc" }, + { 245, "otilde" }, + { 246, "ouml" }, + { 247, "divide" }, + { 248, "oslash" }, + { 249, "ugrave" }, + { 250, "uacute" }, + { 251, "ucirc" }, + { 252, "uuml" }, + { 253, "yacute" }, + { 254, "thorn" }, + { 255, "yuml" }, + { 0, NULL } +}; +#endif + +#ifndef WITH_NOIO +#ifndef WITH_LEAN +static const struct soap_code_map h_error_codes[] = +{ +#ifdef HOST_NOT_FOUND + { HOST_NOT_FOUND, "Host not found" }, +#endif +#ifdef TRY_AGAIN + { TRY_AGAIN, "Try Again" }, +#endif +#ifdef NO_RECOVERY + { NO_RECOVERY, "No Recovery" }, +#endif +#ifdef NO_DATA + { NO_DATA, "No Data" }, +#endif +#ifdef NO_ADDRESS + { NO_ADDRESS, "No Address" }, +#endif + { 0, NULL } +}; +#endif +#endif + +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN +static const struct soap_code_map h_http_error_codes[] = +{ { 200, "OK" }, + { 201, "Created" }, + { 202, "Accepted" }, + { 203, "Non-Authoritative Information" }, + { 204, "No Content" }, + { 205, "Reset Content" }, + { 206, "Partial Content" }, + { 300, "Multiple Choices" }, + { 301, "Moved Permanently" }, + { 302, "Found" }, + { 303, "See Other" }, + { 304, "Not Modified" }, + { 305, "Use Proxy" }, + { 307, "Temporary Redirect" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 402, "Payment Required" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 405, "Method Not Allowed" }, + { 406, "Not Acceptable" }, + { 407, "Proxy Authentication Required" }, + { 408, "Request Time-out" }, + { 409, "Conflict" }, + { 410, "Gone" }, + { 411, "Length Required" }, + { 412, "Precondition Failed" }, + { 413, "Request Entity Too Large" }, + { 414, "Request-URI Too Large" }, + { 415, "Unsupported Media Type" }, + { 416, "Requested range not satisfiable" }, + { 417, "Expectation Failed" }, + { 500, "Internal Server Error" }, + { 501, "Not Implemented" }, + { 502, "Bad Gateway" }, + { 503, "Service Unavailable" }, + { 504, "Gateway Time-out" }, + { 505, "HTTP Version not supported" }, + { 0, NULL } +}; +#endif +#endif + +#ifdef WITH_OPENSSL +static const struct soap_code_map h_ssl_error_codes[] = +{ +#define _SSL_ERROR(e) { e, #e } + _SSL_ERROR(SSL_ERROR_SSL), + _SSL_ERROR(SSL_ERROR_ZERO_RETURN), + _SSL_ERROR(SSL_ERROR_WANT_READ), + _SSL_ERROR(SSL_ERROR_WANT_WRITE), + _SSL_ERROR(SSL_ERROR_WANT_CONNECT), + _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP), + _SSL_ERROR(SSL_ERROR_SYSCALL), + { 0, NULL } +}; +#endif + +#ifndef WITH_LEANER +static const struct soap_code_map mime_codes[] = +{ { SOAP_MIME_7BIT, "7bit" }, + { SOAP_MIME_8BIT, "8bit" }, + { SOAP_MIME_BINARY, "binary" }, + { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" }, + { SOAP_MIME_BASE64, "base64" }, + { SOAP_MIME_IETF_TOKEN, "ietf-token" }, + { SOAP_MIME_X_TOKEN, "x-token" }, + { 0, NULL } +}; +#endif + +#ifdef WIN32 +static int tcp_done = 0; +#endif + +#if defined(HP_UX) && defined(HAVE_GETHOSTBYNAME_R) +extern int h_errno; +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +fsend(struct soap *soap, const char *s, size_t n) +{ register int nwritten, err; +#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) + if (soap->os) + { soap->os->write(s, (std::streamsize)n); + if (soap->os->good()) + return SOAP_OK; + soap->errnum = 0; + return SOAP_EOF; + } +#endif + while (n) + { if (soap_valid_socket(soap->socket)) + { + if (soap->send_timeout) + { for (;;) + { register int r; +#ifdef WITH_OPENSSL + if (soap->ssl) + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, soap->send_timeout); + else +#endif +#ifdef WITH_GNUTLS + if (soap->session) + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, soap->send_timeout); + else +#endif + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout); + if (r > 0) + break; + if (!r) + return SOAP_EOF; + err = soap->errnum; + if (!err) + return soap->error; + if (err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK) + return SOAP_EOF; + } + } +#ifdef WITH_OPENSSL + if (soap->ssl) + nwritten = SSL_write(soap->ssl, s, (int)n); + else if (soap->bio) + nwritten = BIO_write(soap->bio, s, (int)n); + else +#endif +#ifdef WITH_GNUTLS + if (soap->session) + nwritten = gnutls_record_send(soap->session, s, n); + else +#endif +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + { if (soap->peerlen) + nwritten = sendto(soap->socket, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen); + else + nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags); + /* retry and back-off algorithm */ + /* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */ + if (nwritten < 0) + { int udp_repeat; + int udp_delay; + if ((soap->connect_flags & SO_BROADCAST)) + udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */ + else + udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */ + udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */ + do + { tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ERR, -1000 * udp_delay); + if (soap->peerlen) + nwritten = sendto(soap->socket, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen); + else + nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags); + udp_delay <<= 1; + if (udp_delay > 500) /* UDP_UPPER_DELAY */ + udp_delay = 500; + } + while (nwritten < 0 && --udp_repeat > 0); + } + } + else +#endif +#if !defined(PALM) && !defined(AS400) + nwritten = send(soap->socket, s, (int)n, soap->socket_flags); +#else + nwritten = send(soap->socket, (void*)s, n, soap->socket_flags); +#endif + if (nwritten <= 0) + { + register int r = 0; + err = soap_socket_errno(soap->socket); +#ifdef WITH_OPENSSL + if (soap->ssl && (r = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) + { soap->errnum = err; + return SOAP_EOF; + } +#endif +#ifdef WITH_GNUTLS + if (soap->session) + { if (nwritten == GNUTLS_E_INTERRUPTED) + err = SOAP_EINTR; + else if (nwritten == GNUTLS_E_AGAIN) + err = SOAP_EAGAIN; + } +#endif + if (err == SOAP_EWOULDBLOCK || err == SOAP_EAGAIN) + { +#if defined(WITH_OPENSSL) + if (soap->ssl && r == SSL_ERROR_WANT_READ) + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000); + else +#elif defined(WITH_GNUTLS) + if (soap->session && !gnutls_record_get_direction(soap->session)) + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000); + else +#endif + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000); + if (!r && soap->send_timeout) + return SOAP_EOF; + if (r < 0 && soap->errnum != SOAP_EINTR) + return SOAP_EOF; + } + else if (err && err != SOAP_EINTR) + { soap->errnum = err; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + else + { +#ifdef WITH_FASTCGI + nwritten = fwrite((void*)s, 1, n, stdout); + fflush(stdout); +#else +#ifdef UNDER_CE + nwritten = fwrite(s, 1, n, soap->sendfd); +#else +#ifdef VXWORKS +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + nwritten = (httpBlockPut(soap->rpmreqid, (char*)s, n) == 0) ? n : -1; + else +#endif + nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w")); +#else +#ifdef WIN32 + nwritten = _write(soap->sendfd, s, (unsigned int)n); +#else + nwritten = write(soap->sendfd, s, (unsigned int)n); +#endif +#endif +#endif +#endif + if (nwritten <= 0) + { +#ifndef WITH_FASTCGI + err = soap_errno; +#else + err = EOF; +#endif + if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN) + { soap->errnum = err; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + n -= nwritten; + s += nwritten; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_raw(struct soap *soap, const char *s, size_t n) +{ if (!n) + return SOAP_OK; + if (soap->mode & SOAP_IO_LENGTH) + { soap->count += n; +#ifndef WITH_LEANER + if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->error = soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } + if (soap->mode & SOAP_IO) + { register size_t i = SOAP_BUFLEN - soap->bufidx; + while (n >= i) + { memcpy(soap->buf + soap->bufidx, s, i); + soap->bufidx = SOAP_BUFLEN; + if (soap_flush(soap)) + return soap->error; + s += i; + n -= i; + i = SOAP_BUFLEN; + } + memcpy(soap->buf + soap->bufidx, s, n); + soap->bufidx += n; + return SOAP_OK; + } + return soap_flush_raw(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush(struct soap *soap) +{ register size_t n = soap->bufidx; + if (n) + { +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { register int r; + if (soap->fpreparesend && (r = soap->fpreparesend(soap, soap->buf, n))) + return soap->error = r; + } +#endif + soap->bufidx = 0; +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->d_stream->next_in = (Byte*)soap->buf; + soap->d_stream->avail_in = (unsigned int)n; +#ifdef WITH_GZIP + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n); +#endif + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream->avail_in)); + if (deflate(soap->d_stream, Z_NO_FLUSH) != Z_OK) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS)); + return soap->error = SOAP_ZLIB_ERROR; + } + if (!soap->d_stream->avail_out) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN)) + return soap->error; + soap->d_stream->next_out = (Byte*)soap->z_buf; + soap->d_stream->avail_out = SOAP_BUFLEN; + } + } while (soap->d_stream->avail_in); + } + else +#endif + return soap_flush_raw(soap, soap->buf, n); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush_raw(struct soap *soap, const char *s, size_t n) +{ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { register char *t; + if (!(t = (char*)soap_push_block(soap, NULL, n))) + return soap->error = SOAP_EOM; + memcpy(t, s, n); + return SOAP_OK; + } +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { char t[16]; + sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n); + DBGMSG(SENT, t, strlen(t)); + if ((soap->error = soap->fsend(soap, t, strlen(t)))) + return soap->error; + soap->chunksize += n; + } + DBGMSG(SENT, s, n); +#endif + return soap->error = soap->fsend(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send(struct soap *soap, const char *s) +{ if (s) + return soap_send_raw(soap, s, strlen(s)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send2(struct soap *soap, const char *s1, const char *s2) +{ if (soap_send(soap, s1)) + return soap->error; + return soap_send(soap, s2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3) +{ if (soap_send(soap, s1) + || soap_send(soap, s2)) + return soap->error; + return soap_send(soap, s3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static size_t +frecv(struct soap *soap, char *s, size_t n) +{ register int r; + register int retries = 100; /* max 100 retries with non-blocking sockets */ + soap->errnum = 0; +#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) + if (soap->is) + { if (soap->is->good()) + return soap->is->read(s, (std::streamsize)n).gcount(); + return 0; + } +#endif + if (soap_valid_socket(soap->socket)) + { for (;;) + { +#ifdef WITH_OPENSSL + register int err = 0; +#endif +#ifdef WITH_OPENSSL + if (soap->recv_timeout && !soap->ssl) /* SSL: sockets are nonblocking */ +#else + if (soap->recv_timeout) +#endif + { for (;;) + { r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout); + if (r > 0) + break; + if (!r) + return 0; + r = soap->errnum; + if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK) + return 0; + } + } +#ifdef WITH_OPENSSL + if (soap->ssl) + { r = SSL_read(soap->ssl, s, (int)n); + if (r > 0) + return (size_t)r; + err = SSL_get_error(soap->ssl, r); + if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return 0; + } + else if (soap->bio) + { r = BIO_read(soap->bio, s, (int)n); + if (r > 0) + return (size_t)r; + return 0; + } + else +#endif +#ifdef WITH_GNUTLS + if (soap->session) + { r = (int)gnutls_record_recv(soap->session, s, n); + if (r >= 0) + return (size_t)r; + } + else +#endif + { +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + r = recvfrom(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ + soap->peerlen = (size_t)k; +#ifndef WITH_IPV6 + soap->ip = ntohl(soap->peer.sin_addr.s_addr); +#endif + } + else +#endif + r = recv(soap->socket, s, (int)n, soap->socket_flags); +#ifdef PALM + /* CycleSyncDisplay(curStatusMsg); */ +#endif + if (r >= 0) + return (size_t)r; + r = soap_socket_errno(soap->socket); + if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK) + { soap->errnum = r; + return 0; + } + } +#if defined(WITH_OPENSSL) + if (soap->ssl && err == SSL_ERROR_WANT_WRITE) + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5); + else +#elif defined(WITH_GNUTLS) + if (soap->session && gnutls_record_get_direction(soap->session)) + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5); + else +#endif + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5); + if (!r && soap->recv_timeout) + return 0; + if (r < 0) + { r = soap->errnum; + if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK) + return 0; + } + if (retries-- <= 0) + return 0; +#ifdef PALM + r = soap_socket_errno(soap->socket); + if (r != SOAP_EINTR && retries-- <= 0) + { soap->errnum = r; + return 0; + } +#endif + } + } +#ifdef WITH_FASTCGI + return fread(s, 1, n, stdin); +#else +#ifdef UNDER_CE + return fread(s, 1, n, soap->recvfd); +#else +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + r = httpBlockRead(soap->rpmreqid, s, n); + else +#endif +#ifdef WIN32 + r = _read(soap->recvfd, s, (unsigned int)n); +#else + r = read(soap->recvfd, s, (unsigned int)n); +#endif + if (r >= 0) + return (size_t)r; + soap->errnum = soap_errno; + return 0; +#endif +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static soap_wchar +soap_getchunkchar(struct soap *soap) +{ if (soap->bufidx < soap->buflen) + return soap->buf[soap->bufidx++]; + soap->bufidx = 0; + soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket)); + DBGMSG(RECV, soap->buf, soap->buflen); + if (soap->buflen) + return soap->buf[soap->bufidx++]; + return EOF; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +soap_isxdigit(int c) +{ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_raw(struct soap *soap) +{ register size_t ret; +#if !defined(WITH_LEANER) || defined(WITH_ZLIB) + register int r; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { if (soap->d_stream->next_out == Z_NULL) + return EOF; + if (soap->d_stream->avail_in || !soap->d_stream->avail_out) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n")); + soap->d_stream->next_out = (Byte*)soap->buf; + soap->d_stream->avail_out = SOAP_BUFLEN; + r = inflate(soap->d_stream, Z_NO_FLUSH); + if (r == Z_NEED_DICT && soap->z_dict) + r = inflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + ret = soap->buflen = SOAP_BUFLEN - soap->d_stream->avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)ret); + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out)); + soap->z_ratio_in = (float)soap->d_stream->total_in / (float)soap->d_stream->total_out; + soap->d_stream->next_out = Z_NULL; + } + if (ret) + { soap->count += ret; + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n")); + DBGMSG(RECV, soap->buf, ret); + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n----\n")); +#ifndef WITH_LEANER + if (soap->fpreparerecv && (r = soap->fpreparerecv(soap, soap->buf, ret))) + return soap->error = r; +#endif + return SOAP_OK; + } + } + else if (r != Z_BUF_ERROR) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS)); + soap->d_stream->next_out = Z_NULL; + soap->error = SOAP_ZLIB_ERROR; + return EOF; + } + } +zlib_again: + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize) + { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->buflen = soap->z_buflen; + } + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- compressed ----\n")); + } +#endif +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */ + { for (;;) + { register soap_wchar c; + char *t, tmp[8]; + if (soap->chunksize) + { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + soap->chunksize -= ret; + break; + } + t = tmp; + if (!soap->chunkbuflen) + { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + if (!ret) + return soap->ahead = EOF; + } + else + soap->bufidx = soap->buflen; + soap->buflen = soap->chunkbuflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen)); + while (!soap_isxdigit((int)(c = soap_getchunkchar(soap)))) + { if ((int)c == EOF) + return soap->ahead = EOF; + } + do + *t++ = (char)c; + while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + if ((int)c == EOF) + return soap->ahead = EOF; + *t = '\0'; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunk size = %s (hex)\n", tmp)); + soap->chunksize = soap_strtoul(tmp, &t, 16); + if (!soap->chunksize) + { soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n")); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + ret = 0; + soap->ahead = EOF; + break; + } + soap->buflen = soap->bufidx + soap->chunksize; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp)); + if (soap->buflen > soap->chunkbuflen) + { soap->buflen = soap->chunkbuflen; + soap->chunksize -= soap->buflen - soap->bufidx; + soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx))); + } + else if (soap->chunkbuflen) + soap->chunksize = 0; + ret = soap->buflen - soap->bufidx; + if (ret) + break; + } + } + else +#endif + { soap->bufidx = 0; + soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + } +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream->avail_in = (unsigned int)ret; + soap->d_stream->next_out = (Byte*)soap->buf; + soap->d_stream->avail_out = SOAP_BUFLEN; + r = inflate(soap->d_stream, Z_NO_FLUSH); + if (r == Z_NEED_DICT && soap->z_dict) + r = inflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + soap->z_buflen = soap->buflen; + soap->buflen = SOAP_BUFLEN - soap->d_stream->avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)soap->buflen)); + if (ret && !soap->buflen && r != Z_STREAM_END) + goto zlib_again; + ret = soap->buflen; + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated total %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out)); + soap->z_ratio_in = (float)soap->d_stream->total_in / (float)soap->d_stream->total_out; + soap->d_stream->next_out = Z_NULL; + } + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n")); + DBGMSG(RECV, soap->buf, ret); +#ifndef WITH_LEANER + if (soap->fpreparerecv && (r = soap->fpreparerecv(soap, soap->buf, ret))) + return soap->error = r; +#endif + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS)); + soap->d_stream->next_out = Z_NULL; + soap->error = SOAP_ZLIB_ERROR; + return EOF; + } + } +#endif +#ifndef WITH_LEANER + if (soap->fpreparerecv +#ifdef WITH_ZLIB + && soap->zlib_in == SOAP_ZLIB_NONE +#endif + && (r = soap->fpreparerecv(soap, soap->buf + soap->bufidx, ret))) + return soap->error = r; +#endif + soap->count += ret; + return !ret; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_DIME) + { if (soap->dime.buflen) + { char *s; + int i; + unsigned char tmp[12]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n")); + soap->count += soap->dime.buflen - soap->buflen; + soap->buflen = soap->dime.buflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3)); + for (i = -(long)soap->dime.size&3; i > 0; i--) + { soap->bufidx++; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n")); + s = (char*)tmp; + for (i = 12; i > 0; i--) + { *s++ = soap->buf[soap->bufidx++]; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + soap->dime.flags = tmp[0] & 0x7; + soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size)); + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.size) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n")); + soap->dime.buflen = 0; + soap->dime.chunksize = 0; + } + soap->count = soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count)); + return SOAP_OK; + } + if (soap->dime.chunksize) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize)); + if (soap_recv_raw(soap)) + return EOF; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count)); + return SOAP_OK; + } + } +#endif + return soap_recv_raw(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getchar(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + { if (c != EOF) + soap->ahead = 0; + return c; + } + return soap_get1(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const struct soap_code_map* +SOAP_FMAC2 +soap_code(const struct soap_code_map *code_map, const char *str) +{ if (code_map && str) + { while (code_map->string) + { if (!strcmp(str, code_map->string)) /* case sensitive */ + return code_map; + code_map++; + } + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_code_int(const struct soap_code_map *code_map, const char *str, long other) +{ if (code_map) + { while (code_map->string) + { if (!soap_tag_cmp(str, code_map->string)) /* case insensitive */ + return code_map->code; + code_map++; + } + } + return other; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_code_str(const struct soap_code_map *code_map, long code) +{ if (!code_map) + return NULL; + while (code_map->code != code && code_map->string) + code_map++; + return code_map->string; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_code_bits(const struct soap_code_map *code_map, const char *str) +{ register long bits = 0; + if (code_map) + { while (str && *str) + { const struct soap_code_map *p; + for (p = code_map; p->string; p++) + { register size_t n = strlen(p->string); + if (!strncmp(p->string, str, n) && soap_blank((soap_wchar)str[n])) + { bits |= p->code; + str += n; + while (*str > 0 && *str <= 32) + str++; + break; + } + } + if (!p->string) + return 0; + } + } + return bits; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long code) +{ register char *t = soap->tmpbuf; + if (code_map) + { while (code_map->string) + { if (code_map->code & code) + { register const char *s = code_map->string; + if (t != soap->tmpbuf) + *t++ = ' '; + while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1) + *t++ = *s++; + if (t == soap->tmpbuf + sizeof(soap->tmpbuf) - 1) + break; + } + code_map++; + } + } + *t = '\0'; + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static soap_wchar +soap_char(struct soap *soap) +{ char tmp[8]; + register int i; + register soap_wchar c; + register char *s = tmp; + for (i = 0; i < 7; i++) + { c = soap_get1(soap); + if (c == ';' || (int)c == EOF) + break; + *s++ = (char)c; + } + *s = '\0'; + if (*tmp == '#') + { if (tmp[1] == 'x' || tmp[1] == 'X') + return (soap_wchar)soap_strtol(tmp + 2, NULL, 16); + return (soap_wchar)soap_strtol(tmp + 1, NULL, 10); + } + if (!strcmp(tmp, "lt")) + return '<'; + if (!strcmp(tmp, "gt")) + return '>'; + if (!strcmp(tmp, "amp")) + return '&'; + if (!strcmp(tmp, "quot")) + return '"'; + if (!strcmp(tmp, "apos")) + return '\''; +#ifndef WITH_LEAN + return (soap_wchar)soap_code_int(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR); +#else + return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */ +#endif +} +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +#ifndef PALM_1 +soap_wchar +soap_get0(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx]; +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +#ifndef PALM_1 +soap_wchar +soap_get1(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx++]; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_get(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + { if ((int)c != EOF) + soap->ahead = 0; + } + else + c = soap_get1(soap); + while ((int)c != EOF) + { if (soap->cdata) + { if (c == ']') + { c = soap_get1(soap); + if (c == ']') + { c = soap_get0(soap); + if (c == '>') + { soap->cdata = 0; + soap_get1(soap); + c = soap_get1(soap); + } + else + { soap_unget(soap, ']'); + return ']'; + } + } + else + { soap_revget1(soap); + return ']'; + } + } + else + return c; + } + switch (c) + { case '<': + do c = soap_get1(soap); + while (soap_blank(c)); + if (c == '!' || c == '?' || c == '%') + { register int k = 1; + if (c == '!') + { c = soap_get1(soap); + if (c == '[') + { do c = soap_get1(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + break; + soap->cdata = 1; + c = soap_get1(soap); + continue; + } + if (c == '-' && (c = soap_get1(soap)) == '-') + { do + { c = soap_get1(soap); + if (c == '-' && (c = soap_get1(soap)) == '-') + break; + } while ((int)c != EOF); + } + } + else if (c == '?') + c = soap_get_pi(soap); + while ((int)c != EOF) + { if (c == '<') + k++; + else if (c == '>') + { if (--k <= 0) + break; + } + c = soap_get1(soap); + } + if ((int)c == EOF) + break; + c = soap_get1(soap); + continue; + } + if (c == '/') + return SOAP_TT; + soap_revget1(soap); + return SOAP_LT; + case '>': + return SOAP_GT; + case '"': + return SOAP_QT; + case '\'': + return SOAP_AP; + case '&': + return soap_char(soap) | 0x80000000; + } + break; + } + return c; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static soap_wchar +soap_get_pi(struct soap *soap) +{ char buf[64]; + register char *s = buf; + register int i = sizeof(buf); + register soap_wchar c = soap_getchar(soap); + /* This is a quick way to parse XML PI and we could use a callback instead to + * enable applications to intercept processing instructions */ + while ((int)c != EOF && c != '?') + { if (--i > 0) + { if (soap_blank(c)) + c = ' '; + *s++ = (char)c; + } + c = soap_getchar(soap); + } + *s = '\0'; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI \n", buf)); + if (!strncmp(buf, "xml ", 4)) + { s = strstr(buf, " encoding="); + if (s && s[10]) + { if (!soap_tag_cmp(s + 11, "iso-8859-1*") + || !soap_tag_cmp(s + 11, "latin1*")) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to latin1 encoding\n")); + soap->mode |= SOAP_ENC_LATIN; + } + else if (!soap_tag_cmp(s + 11, "utf-8*")) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to utf-8 encoding\n")); + soap->mode &= ~SOAP_ENC_LATIN; + } + } + } + if ((int)c != EOF) + c = soap_getchar(soap); + return c; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_move(struct soap *soap, long n) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n)); + for (; n > 0; n--) + if ((int)soap_getchar(soap) == EOF) + return SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_tell(struct soap *soap) +{ return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pututf8(struct soap *soap, register unsigned long c) +{ char tmp[16]; + if (c < 0x80 && c > 0) + { *tmp = (char)c; + return soap_send_raw(soap, tmp, 1); + } +#ifndef WITH_LEAN + if (c >= 0x80) + { register char *t = tmp; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + *t = '\0'; + } +#else + sprintf(tmp, "&#%lu;", c); +#endif + return soap_send(soap, tmp); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getutf8(struct soap *soap) +{ register soap_wchar c, c1, c2, c3, c4; + c = soap->ahead; + if (c > 0x7F) + { soap->ahead = 0; + return c; + } + c = soap_get(soap); + if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN)) + return c; + c1 = soap_get1(soap); + if (c1 < 0x80) + { soap_revget1(soap); /* doesn't look like this is UTF8 */ + return c; + } + c1 &= 0x3F; + if (c < 0xE0) + return ((soap_wchar)(c & 0x1F) << 6) | c1; + c2 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF0) + return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2; + c3 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF8) + return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3; + c4 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xFC) + return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4; + return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthex(struct soap *soap, const unsigned char *s, int n) +{ char d[2]; + register int i; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (i = 0; i < n; i++) + { register int m = *s++; + d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0')); + m &= 0x0F; + d[1] = (char)(m + (m > 9 ? '7' : '0')); + if (soap_send_raw(soap, d, 2)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_gethex(struct soap *soap, int *n) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_string_in(soap, 0, -1, -1); + return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n); + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register char *s; + register size_t i, k; + if (soap_append_lab(soap, NULL, 0)) + return NULL; + s = soap->labbuf + soap->labidx; + k = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + for (i = 0; i < k; i++) + { register char d1, d2; + register soap_wchar c; + c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = (int)(soap->lablen + i - k); + p = (unsigned char*)soap_malloc(soap, soap->lablen + i - k); + if (p) + memcpy(p, soap->labbuf, soap->lablen + i - k); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#else + if (soap_new_block(soap) == NULL) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, NULL, SOAP_BLKLEN); + if (!s) + { soap_end_block(soap, NULL); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register char d1, d2; + register soap_wchar c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap_end_block(soap, NULL); + soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = (int)soap_size_block(soap, NULL, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putbase64(struct soap *soap, const unsigned char *s, int n) +{ register int i; + register unsigned long m; + char d[4]; + if (!s) + return SOAP_OK; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + d[i] = '='; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_getbase64(struct soap *soap, int *n, int malloc_flag) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_string_in(soap, 0, -1, -1); + return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n); + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register size_t i, k; + register char *s; + if (soap_append_lab(soap, NULL, 2)) + return NULL; + s = soap->labbuf + soap->labidx; + k = soap->lablen - soap->labidx; + soap->labidx = 3 * (soap->lablen / 3); + if (!s) + return NULL; + if (k > 2) + { for (i = 0; i < k - 2; i += 3) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)(soap->lablen + i - k); + p = (unsigned char*)soap_malloc(soap, soap->lablen + i - k); + if (p) + memcpy(p, soap->labbuf, soap->lablen + i - k); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { register int b = soap_base64i[c]; + if (b >= 64) + { soap->error = SOAP_TYPE; + return NULL; + } + m = (m << 6) + b; + j++; + } + else if (!soap_blank(c + '+')) + { soap->error = SOAP_TYPE; + return NULL; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } + } +#else + if (soap_new_block(soap) == NULL) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, NULL, 3 * SOAP_BLKLEN); /* must be multiple of 3 */ + if (!s) + { soap_end_block(soap, NULL); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + i *= 3; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)soap_size_block(soap, NULL, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { int b = soap_base64i[c]; + if (b >= 64) + { soap->error = SOAP_TYPE; + return NULL; + } + m = (m << 6) + b; + j++; + } + else if (!soap_blank(c)) + { soap->error = SOAP_TYPE; + return NULL; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options) +{ /* Check MTOM xop:Include element (within hex/base64Binary) */ + /* TODO: this code to be obsoleted with new import/xop.h conventions */ + int body = soap->body; /* should save type too? */ + if (!soap_peek_element(soap)) + { if (!soap_element_begin_in(soap, "xop:Include", 0, NULL) && *soap->href) + { if (soap_dime_forward(soap, ptr, size, id, type, options)) + return soap->error; + } + if (soap->body && soap_element_end_in(soap, NULL)) + return soap->error; + } + soap->body = body; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options) +{ struct soap_xlist *xp; + *ptr = NULL; + *size = 0; + *id = NULL; + *type = NULL; + *options = NULL; + if (!*soap->href) + return SOAP_OK; + *id = soap_strdup(soap, soap->href); + xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist)); + if (!xp) + return soap->error = SOAP_EOM; + xp->next = soap->xlist; + xp->ptr = ptr; + xp->size = size; + xp->id = *id; + xp->type = type; + xp->options = options; + soap->xlist = xp; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_strdup(struct soap *soap, const char *s) +{ char *t = NULL; + if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1))) + strcpy(t, s); + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +wchar_t * +SOAP_FMAC2 +soap_wstrdup(struct soap *soap, const wchar_t *s) +{ wchar_t *t = NULL; + if (s) + { size_t n = 0; + while (s[n]) + n++; + if ((t = (wchar_t*)soap_malloc(soap, sizeof(wchar_t)*(n+1)))) + memcpy(t, s, sizeof(wchar_t)*(n+1)); + } + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_blist* +SOAP_FMAC2 +soap_new_block(struct soap *soap) +{ struct soap_blist *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist)); + if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist)))) + { soap->error = SOAP_EOM; + return NULL; + } + p->next = soap->blist; + p->ptr = NULL; + p->size = 0; + soap->blist = p; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_push_block(struct soap *soap, struct soap_blist *b, size_t n) +{ char *p; + if (!b) + b = soap->blist; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push block of %u bytes (%u bytes total)\n", (unsigned int)n, (unsigned int)b->size + (unsigned int)n)); + if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + *(char**)p = b->ptr; + *(size_t*)(p + sizeof(char*)) = n; + b->ptr = p; + b->size += n; + return p + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_block(struct soap *soap, struct soap_blist *b) +{ char *p; + if (!b) + b = soap->blist; + if (!b->ptr) + return; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n")); + p = b->ptr; + b->size -= *(size_t*)(p + sizeof(char*)); + b->ptr = *(char**)p; + SOAP_FREE(soap, p); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2) +{ int i; + register struct soap_ilist *ip = NULL; + register struct soap_flist *fp = NULL; +#ifndef WITH_LEANER + register struct soap_xlist *xp = NULL; +#endif + register void *p, **q; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + (p1-p2))); + ip->ptr = (char*)ip->ptr + (p1-p2); + } + for (q = &ip->link; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p)); + *q = (char*)p + (p1-p2); + } + } + for (q = &ip->copy; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p)); + *q = (char*)p + (p1-p2); + } + } + for (fp = ip->flist; fp; fp = fp->next) + { if ((char*)fp->ptr >= start && (char*)fp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp)); + fp->ptr = (char*)fp->ptr + (p1-p2); + } + } + } + } +#ifndef WITH_LEANER + for (xp = soap->xlist; xp; xp = xp->next) + { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:SOAP_STR_EOS, xp->ptr, (char*)xp->ptr + (p1-p2))); + xp->ptr = (unsigned char**)((char*)xp->ptr + (p1-p2)); + xp->size = (int*)((char*)xp->size + (p1-p2)); + xp->type = (char**)((char*)xp->type + (p1-p2)); + xp->options = (char**)((char*)xp->options + (p1-p2)); + } + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static int +soap_has_copies(struct soap *soap, register const char *start, register const char *end) +{ register int i; + register struct soap_ilist *ip = NULL; + register struct soap_flist *fp = NULL; + register const char *p; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { for (p = (const char*)ip->copy; p; p = *(const char**)p) + if (p >= start && p < end) + return SOAP_ERR; + for (fp = ip->flist; fp; fp = fp->next) + if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end) + return SOAP_ERR; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_resolve(struct soap *soap) +{ register int i; + register struct soap_ilist *ip = NULL; + register struct soap_flist *fp = NULL; + short flag; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr) + { register void *p, **q, *r; + q = (void**)ip->link; + ip->link = NULL; + r = ip->ptr; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id)); + while (q) + { p = *q; + *q = r; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r)); + q = (void**)p; + } + } + else if (*ip->id == '#') + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id)); + strcpy(soap->id, ip->id + 1); + return soap->error = SOAP_MISSING_ID; + } + } + } + do + { flag = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size)) + { if (ip->copy) + { register void *p, **q = (void**)ip->copy; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id)); + ip->copy = NULL; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size)); + p = *q; + memcpy(q, ip->ptr, ip->size); + q = (void**)p; + } while (q); + flag = 1; + } + for (fp = ip->flist; fp; fp = ip->flist) + { register unsigned int k = fp->level; + register void *p = ip->ptr; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id)); + while (ip->level < k) + { register void **q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return soap->error; + *q = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q)); + p = (void*)q; + k--; + } + if (fp->fcopy) + fp->fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size); + else + soap_fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size); + ip->flist = fp->next; + SOAP_FREE(soap, fp); + flag = 1; + } + } + } + } + } while (flag); +#ifdef SOAP_DEBUG + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->copy || ip->flist) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution error: forwarded data for id='%s' could not be propagated, please report this problem to the developers\n", ip->id)); + } + } + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n")); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_size_block(struct soap *soap, struct soap_blist *b, size_t n) +{ if (!b) + b = soap->blist; + if (b->ptr) + { b->size -= *(size_t*)(b->ptr + sizeof(char*)) - n; + *(size_t*)(b->ptr + sizeof(char*)) = n; + } + return b->size; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_first_block(struct soap *soap, struct soap_blist *b) +{ char *p, *q, *r; + if (!b) + b = soap->blist; + p = b->ptr; + if (!p) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n")); + r = NULL; + do + { q = *(char**)p; + *(char**)p = r; + r = p; + p = q; + } while (p); + b->ptr = r; + return r + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_next_block(struct soap *soap, struct soap_blist *b) +{ char *p; + if (!b) + b = soap->blist; + p = b->ptr; + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n")); + b->ptr = *(char**)p; + SOAP_FREE(soap, p); + if (b->ptr) + return b->ptr + sizeof(char*) + sizeof(size_t); + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_block_size(struct soap *soap, struct soap_blist *b) +{ if (!b) + b = soap->blist; + return *(size_t*)(b->ptr + sizeof(char*)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end_block(struct soap *soap, struct soap_blist *b) +{ char *p, *q; + if (!b) + b = soap->blist; + if (b) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n")); + for (p = b->ptr; p; p = q) + { q = *(char**)p; + SOAP_FREE(soap, p); + } + if (soap->blist == b) + soap->blist = b->next; + else + { struct soap_blist *bp; + for (bp = soap->blist; bp; bp = bp->next) + { if (bp->next == b) + { bp->next = b->next; + break; + } + } + } + SOAP_FREE(soap, b); + } + DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n")); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_save_block(struct soap *soap, struct soap_blist *b, char *p, int flag) +{ register size_t n; + register char *q, *s; + if (!b) + b = soap->blist; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (unsigned int)b->size, b->ptr, p)); + if (b->size) + { if (!p) + p = (char*)soap_malloc(soap, b->size); + if (p) + { for (s = p, q = soap_first_block(soap, b); q; q = soap_next_block(soap, b)) + { n = soap_block_size(soap, b); +#ifndef WITH_NOIDREF + if (flag) + soap_update_ptrs(soap, q, q + n, s, q); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s)); + memcpy(s, q, n); + s += n; + } + } + else + soap->error = SOAP_EOM; + } + soap_end_block(soap, b); + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsize(struct soap *soap, const char *type, int size) +{ return soap_putsizes(soap, type, &size, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizes(struct soap *soap, const char *type, const int *size, int dim) +{ return soap_putsizesoffsets(soap, type, size, NULL, dim); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim) +{ int i; + if (!type) + return NULL; + if (soap->version == 2) + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), " %d", size[i]); + } + else + { if (offset) + { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]); + } + else + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i]); + } + strcat(soap->type, "]"); + } + return soap->type; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffset(struct soap *soap, int offset) +{ return soap_putoffsets(soap, &offset, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffsets(struct soap *soap, const int *offset, int dim) +{ register int i; + sprintf(soap->arrayOffset, "[%d", offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]); + strcat(soap->arrayOffset, "]"); + return soap->arrayOffset; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_size(const int *size, int dim) +{ register int i, n = size[0]; + for (i = 1; i < dim; i++) + n *= size[i]; + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getoffsets(const char *attr, const int *size, int *offset, int dim) +{ register int i, j = 0; + if (offset) + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += offset[i] = (int)soap_strtol(attr, NULL, 10); + attr = strchr(attr, ','); + } + else + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += (int)soap_strtol(attr, NULL, 10); + attr = strchr(attr, ','); + } + return j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsize(const char *attr1, const char *attr2, int *j) +{ register int n, k; + char *s; + *j = 0; + if (!*attr1) + return -1; + if (*attr1 == '[') + attr1++; + n = 1; + for (;;) + { k = (int)soap_strtol(attr1, &s, 10); + n *= k; + if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1) + return -1; + attr1 = strchr(s, ','); + if (!attr1) + attr1 = strchr(s, ' '); + if (attr2 && *attr2) + { attr2++; + *j *= k; + k = (int)soap_strtol(attr2, &s, 10); + *j += k; + if (k < 0) + return -1; + attr2 = s; + } + if (!attr1) + break; + attr1++; + } + return n - *j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsizes(const char *attr, int *size, int dim) +{ register int i, k, n; + if (!*attr) + return -1; + i = (int)strlen(attr); + n = 1; + do + { for (i = i-1; i >= 0; i--) + if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ') + break; + k = (int)soap_strtol(attr + i + 1, NULL, 10); + n *= size[--dim] = k; + if (k < 0 || n > SOAP_MAXARRAYSIZE) + return -1; + } while (i >= 0 && attr[i] != '['); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getposition(const char *attr, int *pos) +{ register int i, n; + if (!*attr) + return -1; + n = 0; + i = 1; + do + { pos[n++] = (int)soap_strtol(attr + i, NULL, 10); + while (attr[i] && attr[i] != ',' && attr[i] != ']') + i++; + if (attr[i] == ',') + i++; + } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']'); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_nlist * +SOAP_FMAC2 +soap_push_namespace(struct soap *soap, const char *id, const char *ns) +{ register struct soap_nlist *np; + register struct Namespace *p; + register short i = -1; + register size_t n, k; + n = strlen(id); + k = strlen(ns) + 1; + p = soap->local_namespaces; + if (p) + { for (i = 0; p->id; p++, i++) + { if (p->ns && !strcmp(ns, p->ns)) + { if (p->out) + { SOAP_FREE(soap, p->out); + p->out = NULL; + } + break; + } + if (p->out) + { if (!strcmp(ns, p->out)) + break; + } + else if (p->in) + { if (!soap_tag_cmp(ns, p->in)) + { if ((p->out = (char*)SOAP_MALLOC(soap, k))) + strcpy(p->out, ns); + break; + } + } + } + if (!p || !p->id) + i = -1; + } + if (i >= 0) + k = 0; + np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k); + if (!np) + { soap->error = SOAP_EOM; + return NULL; + } + np->next = soap->nlist; + soap->nlist = np; + np->level = soap->level; + np->index = i; + strcpy(np->id, id); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns)); + if (i < 0) + { np->ns = strcpy(np->id + n + 1, ns); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns)); + } + else + { np->ns = NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id)); + } + return np; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_namespace(struct soap *soap) +{ register struct soap_nlist *np, *nq; + for (np = soap->nlist; np && np->level >= soap->level; np = nq) + { nq = np->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop namespace binding (level=%u) '%s'\n", soap->level, np->id)); + SOAP_FREE(soap, np); + } + soap->nlist = np; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_namespace(struct soap *soap, const char *id1, const char *id2, size_t n1, size_t n2) +{ register struct soap_nlist *np = soap->nlist; + const char *s; + while (np && (strncmp(np->id, id1, n1) || np->id[n1])) + np = np->next; + if (np) + { if (!(soap->mode & SOAP_XML_IGNORENS)) + if (np->index < 0 + || ((s = soap->local_namespaces[np->index].id) && (strncmp(s, id2, n2) || (s[n2] && s[n2] != '_')))) + return SOAP_NAMESPACE; + return SOAP_OK; + } + if (n1 == 0) + return (soap->mode & SOAP_XML_IGNORENS) ? SOAP_OK : SOAP_NAMESPACE; + if ((n1 == 3 && n1 == n2 && !strncmp(id1, "xml", 3) && !strncmp(id1, id2, 3)) + || (soap->mode & SOAP_XML_IGNORENS)) + return SOAP_OK; + return soap->error = SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_current_namespace(struct soap *soap, const char *tag) +{ register struct soap_nlist *np; + register const char *s; + if (!tag || !strncmp(tag, "xml", 3)) + return NULL; + np = soap->nlist; + if (!(s = strchr(tag, ':'))) + { while (np && *np->id) /* find default namespace, if present */ + np = np->next; + } + else + { while (np && (strncmp(np->id, tag, s - tag) || np->id[s - tag])) + np = np->next; + if (!np) + soap->error = SOAP_NAMESPACE; + } + if (np) + { if (np->index >= 0) + return soap->namespaces[np->index].ns; + if (np->ns) + return soap_strdup(soap, np->ns); + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_tag_cmp(const char *s, const char *t) +{ for (;;) + { register int c1 = *s; + register int c2 = *t; + if (!c1 || c1 == '"') + break; + if (c2 != '-') + { if (c1 != c2) + { if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + } + if (c1 != c2) + { if (c2 != '*') + return 1; + c2 = *++t; + if (!c2) + return 0; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + for (;;) + { c1 = *s; + if (!c1 || c1 == '"') + break; + if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1)) + return 0; + s++; + } + break; + } + } + s++; + t++; + } + if (*t == '*' && !t[1]) + return 0; + return *t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_tag(struct soap *soap, const char *tag1, const char *tag2) +{ register const char *s, *t; + register int err; + if (!tag1 || !tag2 || !*tag2) + return SOAP_OK; + s = strchr(tag1, ':'); + t = strchr(tag2, ':'); + if (t) + { if (s) + { if (t[1] && SOAP_STRCMP(s + 1, t + 1)) + return SOAP_TAG_MISMATCH; + if (t != tag2 && (err = soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + if (err == SOAP_NAMESPACE) + return SOAP_TAG_MISMATCH; + return err; + } + } + else if (SOAP_STRCMP(tag1, t + 1)) + { return SOAP_TAG_MISMATCH; + } + else if (t != tag2 && (err = soap_match_namespace(soap, tag1, tag2, 0, t - tag2))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + if (err == SOAP_NAMESPACE) + return SOAP_TAG_MISMATCH; + return err; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; + } + if (s) + { if (SOAP_STRCMP(s + 1, tag2)) + return SOAP_TAG_MISMATCH; + } + else if (SOAP_STRCMP(tag1, tag2)) + return SOAP_TAG_MISMATCH; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_array(struct soap *soap, const char *type) +{ if (*soap->arrayType) + if (soap_match_tag(soap, soap->arrayType, type) + && soap_match_tag(soap, soap->arrayType, "xsd:anyType") + && soap_match_tag(soap, soap->arrayType, "xsd:ur-type") + ) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type)); + return SOAP_TAG_MISMATCH; + } + return SOAP_OK; +} +#endif + +/******************************************************************************\ + * + * SSL/TLS + * +\******************************************************************************/ + +/******************************************************************************/ +#ifdef WITH_OPENSSL +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_rand() +{ unsigned char buf[4]; + if (!soap_ssl_init_done) + soap_ssl_init(); + RAND_pseudo_bytes(buf, 4); + return *(int*)buf; +} +#endif +#endif + +/******************************************************************************/ +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_server_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *dhfile, const char *randfile, const char *sid) +{ int err; + soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + soap->crlfile = NULL; +#ifdef WITH_OPENSSL + soap->dhfile = dhfile; + soap->randfile = randfile; +#endif + soap->ssl_flags = flags | (dhfile == NULL ? SOAP_SSL_RSA : 0); +#ifdef WITH_GNUTLS + if (dhfile) + { char *s; + int n = (int)soap_strtoul(dhfile, &s, 10); + if (!soap->dh_params) + gnutls_dh_params_init(&soap->dh_params); + /* if dhfile is numeric, treat it as a key length to generate DH params which can take a while */ + if (n >= 512 && s && *s == '\0') + gnutls_dh_params_generate2(soap->dh_params, (unsigned int)n); + else + { unsigned int dparams_len; + unsigned char dparams_buf[1024]; + FILE *fd = fopen(dhfile, "r"); + if (!fd) + return soap_set_receiver_error(soap, "SSL/TLS error", "Invalid DH file", SOAP_SSL_ERROR); + dparams_len = (unsigned int)fread(dparams_buf, 1, sizeof(dparams_buf), fd); + fclose(fd); + gnutls_datum_t dparams = { dparams_buf, dparams_len }; + if (gnutls_dh_params_import_pkcs3(soap->dh_params, &dparams, GNUTLS_X509_FMT_PEM)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Invalid DH file", SOAP_SSL_ERROR); + } + } + else + { if (!soap->rsa_params) + gnutls_rsa_params_init(&soap->rsa_params); + gnutls_rsa_params_generate2(soap->rsa_params, SOAP_SSL_RSA_BITS); + } + if (soap->session) + { gnutls_deinit(soap->session); + soap->session = NULL; + } + if (soap->xcred) + { gnutls_certificate_free_credentials(soap->xcred); + soap->xcred = NULL; + } +#endif + err = soap->fsslauth(soap); +#ifdef WITH_OPENSSL + if (!err) + { if (sid) + SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, (unsigned int)strlen(sid)); + else + SSL_CTX_set_session_cache_mode(soap->ctx, SSL_SESS_CACHE_OFF); + } +#endif + return err; +} +#endif +#endif + +/******************************************************************************/ +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_client_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *randfile) +{ soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + soap->ssl_flags = SOAP_SSL_CLIENT | flags; +#ifdef WITH_OPENSSL + soap->dhfile = NULL; + soap->randfile = randfile; + soap->fsslverify = (flags & SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE) == 0 ? ssl_verify_callback : ssl_verify_callback_allow_expired_certificate; +#endif +#ifdef WITH_GNUTLS + if (soap->session) + { gnutls_deinit(soap->session); + soap->session = NULL; + } + if (soap->xcred) + { gnutls_certificate_free_credentials(soap->xcred); + soap->xcred = NULL; + } +#endif + return soap->fsslauth(soap); +} +#endif +#endif + +/******************************************************************************/ +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_ssl_init() +{ /* Note: for MT systems, the main program MUST call soap_ssl_init() before any threads are started */ + if (!soap_ssl_init_done) + { soap_ssl_init_done = 1; +#ifdef WITH_OPENSSL + SSL_library_init(); +#ifndef WITH_LEAN + SSL_load_error_strings(); +#endif + if (!RAND_load_file("/dev/urandom", 1024)) + { char buf[1024]; + RAND_seed(buf, sizeof(buf)); + while (!RAND_status()) + { int r = rand(); + RAND_seed(&r, sizeof(int)); + } + } +#endif +#ifdef WITH_GNUTLS +# if defined(HAVE_PTHREAD_H) + gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); +# elif defined(HAVE_PTH_H) + gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); +# endif + gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); + gcry_control(GCRYCTL_DISABLE_SECMEM, 0); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); /* libgcrypt init done */ + gnutls_global_init(); +#endif + } +} +#endif +#endif + +/******************************************************************************/ +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifndef PALM_1 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_ssl_error(struct soap *soap, int ret) +{ +#ifdef WITH_OPENSSL + int err = SSL_get_error(soap->ssl, ret); + const char *msg = soap_code_str(h_ssl_error_codes, err); + if (msg) + strcpy(soap->msgbuf, msg); + else + return ERR_error_string(err, soap->msgbuf); + if (ERR_peek_error()) + { unsigned long r; + strcat(soap->msgbuf, "\n"); + while ((r = ERR_get_error())) + ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf)); + } + else + { switch (ret) + { case 0: + strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information."); + break; + case -1: + sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno)); + break; + } + } + return soap->msgbuf; +#endif +#ifdef WITH_GNUTLS + return gnutls_strerror(ret); +#endif +} +#endif +#endif + +/******************************************************************************/ +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifndef PALM_1 +static int +ssl_auth_init(struct soap *soap) +{ +#ifdef WITH_OPENSSL + long flags; + int mode; + if (!soap_ssl_init_done) + soap_ssl_init(); + ERR_clear_error(); + if (!soap->ctx) + { if (!(soap->ctx = SSL_CTX_new(SSLv23_method()))) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't setup context", SOAP_SSL_ERROR); + /* The following alters the behavior of SSL read/write: */ +#if 0 + SSL_CTX_set_mode(soap->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY); +#endif + } + if (soap->randfile) + { if (!RAND_load_file(soap->randfile, -1)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't load randomness", SOAP_SSL_ERROR); + } + if (soap->cafile || soap->capath) + { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read CA file", SOAP_SSL_ERROR); + if (soap->cafile && (soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + SSL_CTX_set_client_CA_list(soap->ctx, SSL_load_client_CA_file(soap->cafile)); + } + if (!(soap->ssl_flags & SOAP_SSL_NO_DEFAULT_CA_PATH)) + { if (!SSL_CTX_set_default_verify_paths(soap->ctx)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR); + } +/* This code assumes a typical scenario, see alternative code below */ + if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read certificate key file", SOAP_SSL_ERROR); + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + } + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read key file", SOAP_SSL_ERROR); + } +/* Suggested alternative approach to check the key file for certs (cafile=NULL):*/ +#if 0 + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + } + if (!soap->cafile || !SSL_CTX_use_certificate_chain_file(soap->ctx, soap->cafile)) + { if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read certificate or key file", SOAP_SSL_ERROR); + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read key file", SOAP_SSL_ERROR); + } + } +#endif + if ((soap->ssl_flags & SOAP_SSL_RSA)) + { RSA *rsa = RSA_generate_key(SOAP_SSL_RSA_BITS, RSA_F4, NULL, NULL); + if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa)) + { if (rsa) + RSA_free(rsa); + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't set RSA key", SOAP_SSL_ERROR); + } + RSA_free(rsa); + } + else if (soap->dhfile) + { DH *dh = 0; + char *s; + int n = (int)soap_strtoul(soap->dhfile, &s, 10); + /* if dhfile is numeric, treat it as a key length to generate DH params which can take a while */ + if (n >= 512 && s && *s == '\0') + dh = DH_generate_parameters(n, 2/*or 5*/, NULL, NULL); + else + { BIO *bio; + bio = BIO_new_file(soap->dhfile, "r"); + if (!bio) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read DH file", SOAP_SSL_ERROR); + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + } + if (!dh || DH_check(dh, &n) != 1 || SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0) + { if (dh) + DH_free(dh); + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't set DH parameters", SOAP_SSL_ERROR); + } + DH_free(dh); + } + flags = (SSL_OP_ALL | SSL_OP_NO_SSLv2); + if ((soap->ssl_flags & SOAP_SSLv3)) + flags |= SSL_OP_NO_TLSv1; + if ((soap->ssl_flags & SOAP_TLSv1)) + flags |= SSL_OP_NO_SSLv3; +#ifdef SSL_OP_NO_TICKET + /* TLS extension is enabled by default in OPENSSL v0.9.8k + Disable it by adding SSL_OP_NO_TICKET */ + flags |= SSL_OP_NO_TICKET; +#endif + SSL_CTX_set_options(soap->ctx, flags); + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + mode = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); + else if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION)) + mode = SSL_VERIFY_PEER; + else + mode = SSL_VERIFY_NONE; + SSL_CTX_set_verify(soap->ctx, mode, soap->fsslverify); +#if (OPENSSL_VERSION_NUMBER < 0x00905100L) + SSL_CTX_set_verify_depth(soap->ctx, 1); +#else + SSL_CTX_set_verify_depth(soap->ctx, 9); +#endif +#endif +#ifdef WITH_GNUTLS + int ret; + if (!soap_ssl_init_done) + soap_ssl_init(); + if (!soap->xcred) + { gnutls_certificate_allocate_credentials(&soap->xcred); + if (soap->cafile) + { if (gnutls_certificate_set_x509_trust_file(soap->xcred, soap->cafile, GNUTLS_X509_FMT_PEM) < 0) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read CA file", SOAP_SSL_ERROR); + } + if (soap->crlfile) + { if (gnutls_certificate_set_x509_crl_file(soap->xcred, soap->crlfile, GNUTLS_X509_FMT_PEM) < 0) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read CRL file", SOAP_SSL_ERROR); + } + if (soap->keyfile) + { if (gnutls_certificate_set_x509_key_file(soap->xcred, soap->keyfile, soap->keyfile, GNUTLS_X509_FMT_PEM) < 0) /* TODO: GNUTLS need to concat cert and key in single key file */ + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't read key file", SOAP_SSL_ERROR); + } + } + if ((soap->ssl_flags & SOAP_SSL_CLIENT)) + { gnutls_init(&soap->session, GNUTLS_CLIENT); + if (soap->cafile || soap->crlfile || soap->keyfile) + { ret = gnutls_priority_set_direct(soap->session, "PERFORMANCE", NULL); + if (ret < 0) + return soap_set_receiver_error(soap, soap_ssl_error(soap, ret), "SSL/TLS set priority error", SOAP_SSL_ERROR); + gnutls_credentials_set(soap->session, GNUTLS_CRD_CERTIFICATE, soap->xcred); + } + else + { if (!soap->acred) + gnutls_anon_allocate_client_credentials(&soap->acred); + gnutls_init(&soap->session, GNUTLS_CLIENT); + gnutls_priority_set_direct(soap->session, "PERFORMANCE:+ANON-DH:!ARCFOUR-128", NULL); + gnutls_credentials_set(soap->session, GNUTLS_CRD_ANON, soap->acred); + } + } + else + { if (!soap->keyfile) + return soap_set_receiver_error(soap, "SSL/TLS error", "No key file: anonymous server authentication not supported in this release", SOAP_SSL_ERROR); + if ((soap->ssl_flags & SOAP_SSL_RSA) && soap->rsa_params) + gnutls_certificate_set_rsa_export_params(soap->xcred, soap->rsa_params); + else if (soap->dh_params) + gnutls_certificate_set_dh_params(soap->xcred, soap->dh_params); + if (!soap->cache) + gnutls_priority_init(&soap->cache, "NORMAL", NULL); + gnutls_init(&soap->session, GNUTLS_SERVER); + gnutls_priority_set(soap->session, soap->cache); + gnutls_credentials_set(soap->session, GNUTLS_CRD_CERTIFICATE, soap->xcred); + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + gnutls_certificate_server_set_request(soap->session, GNUTLS_CERT_REQUEST); + gnutls_session_enable_compatibility_mode(soap->session); + if ((soap->ssl_flags & SOAP_TLSv1)) + { int protocol_priority[] = { GNUTLS_TLS1_0, 0 }; + if (gnutls_protocol_set_priority(soap->session, protocol_priority) != GNUTLS_E_SUCCESS) + return soap_set_receiver_error(soap, "SSL/TLS error", "Can't set TLS v1.0 protocol", SOAP_SSL_ERROR); + } + } +#endif + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_OPENSSL +#ifndef PALM_1 +static int +ssl_password(char *buf, int num, int rwflag, void *userdata) +{ if (num < (int)strlen((char*)userdata) + 1) + return 0; + return (int)strlen(strcpy(buf, (char*)userdata)); +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_OPENSSL +#ifndef PALM_1 +static int +ssl_verify_callback(int ok, X509_STORE_CTX *store) +{ +#ifdef SOAP_DEBUG + if (!ok) + { char data[256]; + X509 *cert = X509_STORE_CTX_get_current_cert(store); + fprintf(stderr, "SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store))); + X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate issuer %s\n", data); + X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate subject %s\n", data); + } +#endif + /* Note: return 1 to continue, but unsafe progress will be terminated by OpenSSL */ + return ok; +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_OPENSSL +#ifndef PALM_1 +static int +ssl_verify_callback_allow_expired_certificate(int ok, X509_STORE_CTX *store) +{ ok = ssl_verify_callback(ok, store); + if (ok == 0 && X509_STORE_CTX_get_error(store) == X509_V_ERR_CERT_HAS_EXPIRED) + { +#ifdef SOAP_DEBUG + fprintf(stderr, "ignoring certificate expiration\n"); +#endif + X509_STORE_CTX_set_error(store, X509_V_OK); + ok = 1; + } + /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */ + return ok; +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_GNUTLS +static const char * +ssl_verify(struct soap *soap, const char *host) +{ unsigned int status; + const char *err = NULL; + int r = gnutls_certificate_verify_peers2(soap->session, &status); + if (r < 0) + err = "Certificate verify error"; + else if ((status & GNUTLS_CERT_INVALID)) + err = "The certificate is not trusted"; + else if ((status & GNUTLS_CERT_SIGNER_NOT_FOUND)) + err = "The certificate hasn't got a known issuer"; + else if ((status & GNUTLS_CERT_REVOKED)) + err = "The certificate has been revoked"; + else if (gnutls_certificate_type_get(soap->session) == GNUTLS_CRT_X509) + { gnutls_x509_crt_t cert; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size; + if (gnutls_x509_crt_init(&cert) < 0) + err = "Could not get X509 certificates"; + else if ((cert_list = gnutls_certificate_get_peers(soap->session, &cert_list_size)) == NULL) + err = "Could not get X509 certificates"; + else if (gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) + err = "Error parsing X509 certificate"; + else if (!(soap->ssl_flags & SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE) && gnutls_x509_crt_get_expiration_time(cert) < time(NULL)) + err = "The certificate has expired"; + else if (!(soap->ssl_flags & SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE) && gnutls_x509_crt_get_activation_time(cert) > time(NULL)) + err = "The certificate is not yet activated"; + else if (host && !(soap->ssl_flags & SOAP_SSL_SKIP_HOST_CHECK)) + { if (!gnutls_x509_crt_check_hostname(cert, host)) + err = "Certificate host name mismatch"; + } + gnutls_x509_crt_deinit(cert); + } + return err; +} +#endif + +/******************************************************************************/ +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_accept(struct soap *soap) +{ SOAP_SOCKET fd = soap->socket; +#ifdef WITH_OPENSSL + BIO *bio; + int retries, r, s; + if (!soap_valid_socket(fd)) + return soap_set_receiver_error(soap, "SSL/TLS error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR); + soap->ssl_flags &= ~SOAP_SSL_CLIENT; + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + return soap->error; + if (!soap->ssl) + { soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + return soap_set_receiver_error(soap, "SSL/TLS error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + } + else + SSL_clear(soap->ssl); + bio = BIO_new_socket((int)fd, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, bio, bio); + /* Set SSL sockets to non-blocking */ + retries = 0; + if (soap->accept_timeout) + { SOAP_SOCKNONBLOCK(fd) + retries = 10*soap->accept_timeout; + } + if (retries <= 0) + retries = 100; /* timeout: 10 sec retries, 100 times 0.1 sec */ + while ((r = SSL_accept(soap->ssl)) <= 0) + { int err; + if (retries-- <= 0) + break; + err = SSL_get_error(soap->ssl, r); + if (err == SSL_ERROR_WANT_ACCEPT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + { if (err == SSL_ERROR_WANT_READ) + s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000); + else + s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000); + if (s < 0 && soap->errnum != SOAP_EINTR) + break; + } + else + { soap->errnum = soap_socket_errno(fd); + break; + } + } + if (r <= 0) + { soap_set_receiver_error(soap, soap_ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + soap_closesock(soap); + return SOAP_SSL_ERROR; + } + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + { X509 *peer; + int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_closesock(soap); + return soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in soap_ssl_accept()", SOAP_SSL_ERROR); + } + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_closesock(soap); + return soap_set_sender_error(soap, "SSL/TLS error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR); + } + X509_free(peer); + } +#endif +#ifdef WITH_GNUTLS + int retries = 0, r; + if (!soap_valid_socket(fd)) + return soap_set_receiver_error(soap, "SSL/TLS error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR); + soap->ssl_flags &= ~SOAP_SSL_CLIENT; + if (!soap->session && (soap->error = soap->fsslauth(soap))) + { soap_closesock(soap); + return soap->error; + } + gnutls_transport_set_ptr(soap->session, (gnutls_transport_ptr_t)(long)fd); + /* Set SSL sockets to non-blocking */ + if (soap->accept_timeout) + { SOAP_SOCKNONBLOCK(fd) + retries = 10*soap->accept_timeout; + } + if (retries <= 0) + retries = 100; /* timeout: 10 sec retries, 100 times 0.1 sec */ + while ((r = gnutls_handshake(soap->session))) + { int s; + /* GNUTLS repeat handhake when GNUTLS_E_AGAIN */ + if (retries-- <= 0) + break; + if (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED) + { if (!gnutls_record_get_direction(soap->session)) + s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000); + else + s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000); + if (s < 0 && soap->errnum != SOAP_EINTR) + break; + } + else + { soap->errnum = soap_socket_errno(fd); + break; + } + } + if (r) + { soap_closesock(soap); + return soap_set_receiver_error(soap, soap_ssl_error(soap, r), "SSL/TLS handshake failed", SOAP_SSL_ERROR); + } + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + { const char *err = ssl_verify(soap, NULL); + if (err) + { soap_closesock(soap); + return soap_set_receiver_error(soap, "SSL/TLS error", err, SOAP_SSL_ERROR); + } + } +#endif + if (soap->recv_timeout || soap->send_timeout) + SOAP_SOCKNONBLOCK(fd) + else + SOAP_SOCKBLOCK(fd) + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; + return SOAP_OK; +} +#endif +#endif +#endif + +/******************************************************************************\ + * + * TCP/UDP [SSL/TLS] IPv4 and IPv6 + * +\******************************************************************************/ + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_init(struct soap *soap) +{ soap->errmode = 1; +#ifdef WIN32 + if (tcp_done) + return 0; + else + { WSADATA w; + if (WSAStartup(MAKEWORD(1, 1), &w)) + return -1; + tcp_done = 1; + } +#endif + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +tcp_error(struct soap *soap) +{ register const char *msg = NULL; + switch (soap->errmode) + { case 0: + msg = soap_strerror(soap); + break; + case 1: + msg = "WSAStartup failed"; + break; + case 2: + { +#ifndef WITH_LEAN + msg = soap_code_str(h_error_codes, soap->errnum); + if (!msg) +#endif + { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum); + msg = soap->msgbuf; + } + } + } + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_IPV6 +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr) +{ soap_int32 iadd = -1; + struct hostent hostent, *host = &hostent; +#ifdef VXWORKS + int hostint; + /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */ + iadd = inet_addr((char*)addr); +#else +#if defined(_AIX43) || ((defined(TRU64) || defined(HP_UX)) && defined(HAVE_GETHOSTBYNAME_R)) + struct hostent_data ht_data; +#endif +#ifdef AS400 + iadd = inet_addr((void*)addr); +#else + iadd = inet_addr(addr); +#endif +#endif + if (iadd != -1) + { memcpy(inaddr, &iadd, sizeof(iadd)); + return SOAP_OK; + } +#if defined(__GLIBC__) || (defined(HAVE_GETHOSTBYNAME_R) && (defined(FREEBSD) || defined(__FreeBSD__))) + if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0) + host = NULL; +#elif defined(_AIX43) || ((defined(TRU64) || defined(HP_UX)) && defined(HAVE_GETHOSTBYNAME_R)) + memset((void*)&ht_data, 0, sizeof(ht_data)); + if (gethostbyname_r(addr, &hostent, &ht_data) < 0) + { host = NULL; + soap->errnum = h_errno; + } +#elif defined(HAVE_GETHOSTBYNAME_R) + host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum); +#elif defined(VXWORKS) + /* If the DNS resolver library resolvLib has been configured in the vxWorks + * image, a query for the host IP address is sent to the DNS server, if the + * name was not found in the local host table. */ + hostint = hostGetByName((char*)addr); + if (hostint == ERROR) + { host = NULL; + soap->errnum = soap_errno; + } +#else +#ifdef AS400 + if (!(host = gethostbyname((void*)addr))) + soap->errnum = h_errno; +#else + if (!(host = gethostbyname(addr))) + soap->errnum = h_errno; +#endif +#endif + if (!host) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n")); + return SOAP_ERR; + } +#ifdef VXWORKS + inaddr->s_addr = hostint; +#else + memcpy(inaddr, host->h_addr, host->h_length); +#endif + return SOAP_OK; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static SOAP_SOCKET +tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) +{ +#ifdef WITH_IPV6 + struct addrinfo hints, *res, *ressave; +#endif + SOAP_SOCKET fd; + int err = 0; +#ifndef WITH_LEAN +#ifndef WITH_WIN32 + int len = SOAP_BUFLEN; +#else + int len = SOAP_BUFLEN + 1; /* speeds up windows xfer */ +#endif + int set = 1; +#endif +#if !defined(WITH_LEAN) || defined(WITH_OPENSSL) || defined(WITH_GNUTLS) + int retries; +#endif + if (soap_valid_socket(soap->socket)) + soap->fclosesocket(soap, soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + if (tcp_init(soap)) + { soap->errnum = 0; + soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->errmode = 0; +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + hints.ai_socktype = SOCK_DGRAM; + else +#endif + hints.ai_socktype = SOCK_STREAM; + soap->errmode = 2; + if (soap->proxy_host) + err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res); + else + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res); + if (err) + { soap_set_sender_error(soap, SOAP_GAI_STRERROR(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + ressave = res; +again: + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + soap->errmode = 0; +#else +#ifndef WITH_LEAN +again: +#endif +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + fd = socket(AF_INET, SOCK_DGRAM, 0); + else +#endif + fd = socket(AF_INET, SOCK_STREAM, 0); +#endif + if (!soap_valid_socket(fd)) + { +#ifdef WITH_IPV6 + if (res->ai_next) + { res = res->ai_next; + goto again; + } +#endif + soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->connect_flags == SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = soap->linger_time; + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + } + else if (soap->connect_flags && setsockopt(fd, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + if ((soap->keep_alive || soap->tcp_keep_alive) && setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_KEEPIDLE + if (soap->tcp_keep_idle && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&(soap->tcp_keep_idle), sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPIDLE failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#endif +#ifdef TCP_KEEPINTVL + if (soap->tcp_keep_intvl && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&(soap->tcp_keep_intvl), sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPINTVL failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#endif +#ifdef TCP_KEEPCNT + if (soap->tcp_keep_cnt && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPCNT, (char*)&(soap->tcp_keep_cnt), sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPCNT failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#endif +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#endif +#ifdef WITH_IPV6 + if ((soap->omode & SOAP_IO_UDP) && soap->ipv6_multicast_if) + { struct sockaddr_in6 *in6addr = (struct sockaddr_in6*)res->ai_addr; + in6addr->sin6_scope_id = soap->ipv6_multicast_if; + } +#endif +#ifdef IP_MULTICAST_TTL + if ((soap->omode & SOAP_IO_UDP) && soap->ipv4_multicast_if && !soap->ipv6_multicast_if) + { if (soap->ipv4_multicast_ttl > 0) + { char ttl = (char)(soap->ipv4_multicast_ttl); + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_TTL failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + } +#ifndef WINDOWS + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)soap->ipv4_multicast_if, sizeof(struct in_addr))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_IF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } +#else +#ifndef IP_MULTICAST_IF +#define IP_MULTICAST_IF 2 +#endif + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)soap->ipv4_multicast_if, sizeof(struct in_addr))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_IF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } +#endif + } +#endif +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port)); +#ifndef WITH_IPV6 + soap->peerlen = sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->peer.sin_family = AF_INET; + soap->errmode = 2; + if (soap->proxy_host) + { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + soap->peer.sin_port = htons((short)soap->proxy_port); + } + else + { if (soap->fresolve(soap, host, &soap->peer.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + soap->peer.sin_port = htons((short)port); + } + soap->errmode = 0; +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + return fd; +#endif +#else + if ((soap->omode & SOAP_IO_UDP)) + { memcpy(&soap->peer, res->ai_addr, res->ai_addrlen); + soap->peerlen = res->ai_addrlen; + freeaddrinfo(ressave); + return fd; + } +#endif +#ifndef WITH_LEAN + if (soap->connect_timeout) + SOAP_SOCKNONBLOCK(fd) + else + SOAP_SOCKBLOCK(fd) + retries = 10; +#endif + for (;;) + { +#ifdef WITH_IPV6 + if (connect(fd, res->ai_addr, (int)res->ai_addrlen)) +#else + if (connect(fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer))) +#endif + { err = soap_socket_errno(fd); +#ifndef WITH_LEAN + if (err == SOAP_EADDRINUSE) + { soap->fclosesocket(soap, fd); + if (retries-- > 0) + goto again; + } + else if (soap->connect_timeout && (err == SOAP_EINPROGRESS || err == SOAP_EAGAIN || err == SOAP_EWOULDBLOCK)) + { + SOAP_SOCKLEN_T k; + for (;;) + { register int r; + r = tcp_select(soap, fd, SOAP_TCP_SELECT_SND, soap->connect_timeout); + if (r > 0) + break; + if (!r) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + r = soap->errnum; + if (r != SOAP_EINTR) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + } + k = (SOAP_SOCKLEN_T)sizeof(soap->errnum); + if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum) /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ + break; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + if (!soap->errnum) + soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } +#endif +#ifdef WITH_IPV6 + if (res->ai_next) + { res = res->ai_next; + soap->fclosesocket(soap, fd); + goto again; + } +#endif + if (err && err != SOAP_EINTR) + { soap->errnum = err; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); +#ifdef WITH_IPV6 + freeaddrinfo(ressave); +#endif + return SOAP_INVALID_SOCKET; + } + } + else + break; + } +#ifdef WITH_IPV6 + soap->peerlen = 0; /* IPv6: already connected so use send() */ + freeaddrinfo(ressave); +#endif + soap->socket = fd; + soap->imode &= ~SOAP_ENC_SSL; + soap->omode &= ~SOAP_ENC_SSL; + if (!soap_tag_cmp(endpoint, "https:*")) + { +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) +#ifdef WITH_OPENSSL + BIO *bio; +#endif + int r; + if (soap->proxy_host) + { soap_mode m = soap->mode; /* preserve settings */ + soap_mode om = soap->omode; /* make sure we only parse HTTP */ + size_t n = soap->count; /* save the content length */ + const char *userid, *passwd; + soap->omode &= ~SOAP_ENC; /* mask IO and ENC */ + soap->omode |= SOAP_IO_BUFFER; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to %s proxy server\n", soap->proxy_http_version)); + sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->proxy_http_version); + if (soap_begin_send(soap) + || (soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL))) + { soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } +#ifndef WITH_LEAN + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262)); + if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + { soap->fclosesocket(soap, fd); + return soap->error; + } + } +#endif + if ((soap->error = soap->fposthdr(soap, NULL, NULL)) + || soap_flush(soap)) + { soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + soap->omode = om; + om = soap->imode; + soap->imode &= ~SOAP_ENC; /* mask IO and ENC */ + userid = soap->userid; /* preserve */ + passwd = soap->passwd; /* preserve */ + if ((soap->error = soap->fparse(soap))) + { soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + soap->userid = userid; /* restore */ + soap->passwd = passwd; /* restore */ + soap->imode = om; /* restore */ + soap->count = n; /* restore */ + if (soap_begin_send(soap)) + { soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + if (endpoint) + strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint)-1); /* restore */ + soap->mode = m; + } +#ifdef WITH_OPENSSL + soap->ssl_flags |= SOAP_SSL_CLIENT; + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + { soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + if (!soap->ssl) + { soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + { soap->fclosesocket(soap, fd); + soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; + } + } + else + SSL_clear(soap->ssl); + if (soap->session) + { if (!strcmp(soap->session_host, host) && soap->session_port == port) + SSL_set_session(soap->ssl, soap->session); + SSL_SESSION_free(soap->session); + soap->session = NULL; + } + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; + bio = BIO_new_socket((int)fd, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, bio, bio); + /* Connect timeout: set SSL sockets to non-blocking */ + retries = 0; + if (soap->connect_timeout) + { SOAP_SOCKNONBLOCK(fd) + retries = 10*soap->connect_timeout; + } + else + SOAP_SOCKBLOCK(fd) + if (retries <= 0) + retries = 100; /* timeout: 10 sec retries, 100 times 0.1 sec */ + /* Try connecting until success or timeout (when nonblocking) */ + do + { if ((r = SSL_connect(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + { register int s; + if (err == SSL_ERROR_WANT_READ) + s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000); + else + s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000); + if (s < 0 && soap->errnum != SOAP_EINTR) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "SSL_connect/select error in tcp_connect\n")); + soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL_connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + if (s == 0 && retries-- <= 0) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "SSL/TLS connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "SSL_connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + } + else + { soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL_connect error in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + } + } while (!SSL_is_init_finished(soap->ssl)); + /* Set SSL sockets to nonblocking */ + SOAP_SOCKNONBLOCK(fd) + /* Check server credentials when required */ + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION)) + { int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL/TLS certificate presented by peer cannot be verified in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + if (!(soap->ssl_flags & SOAP_SSL_SKIP_HOST_CHECK)) + { X509_NAME *subj; + int ext_count; + int ok = 0; + X509 *peer; + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_set_sender_error(soap, "SSL/TLS error", "No SSL/TLS certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + ext_count = X509_get_ext_count(peer); + if (ext_count > 0) + { int i; + for (i = 0; i < ext_count; i++) + { X509_EXTENSION *ext = X509_get_ext(peer, i); + const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); + if (ext_str && !strcmp(ext_str, "subjectAltName")) + { X509V3_EXT_METHOD *meth = (X509V3_EXT_METHOD*)X509V3_EXT_get(ext); + void *ext_data; +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) + const unsigned char *data; +#else + unsigned char *data; +#endif + STACK_OF(CONF_VALUE) *val; + int j; + if (!meth) + break; + data = ext->value->data; +#if (OPENSSL_VERSION_NUMBER > 0x00907000L) + if (meth->it) + ext_data = ASN1_item_d2i(NULL, &data, ext->value->length, ASN1_ITEM_ptr(meth->it)); + else + { /* OpenSSL not perfectly portable at this point (?): + Some compilers appear to prefer + meth->d2i(NULL, (const unsigned char**)&data, ... + and others prefer + meth->d2i(NULL, &data, ext->value->length); + */ + ext_data = meth->d2i(NULL, &data, ext->value->length); + } +#else + ext_data = meth->d2i(NULL, &data, ext->value->length); +#endif + if (ext_data) + { val = meth->i2v(meth, ext_data, NULL); + if (val) + { for (j = 0; j < sk_CONF_VALUE_num(val); j++) + { CONF_VALUE *nval = sk_CONF_VALUE_value(val, j); + if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host)) + { ok = 1; + break; + } + } + sk_CONF_VALUE_pop_free(val, X509V3_conf_free); + } +#if (OPENSSL_VERSION_NUMBER > 0x00907000L) + if (meth->it) + ASN1_item_free((ASN1_VALUE*)ext_data, ASN1_ITEM_ptr(meth->it)); + else + meth->ext_free(ext_data); +#else + meth->ext_free(ext_data); +#endif + } + } + if (ok) + break; + } + } + if (!ok && (subj = X509_get_subject_name(peer))) + { int i = -1; + do + { ASN1_STRING *name; + i = X509_NAME_get_index_by_NID(subj, NID_commonName, i); + if (i == -1) + break; + name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i)); + if (name) + { if (!soap_tag_cmp(host, (const char*)M_ASN1_STRING_data(name))) + ok = 1; + else + { unsigned char *tmp = NULL; + ASN1_STRING_to_UTF8(&tmp, name); + if (tmp) + { if (!soap_tag_cmp(host, (const char*)tmp)) + ok = 1; + OPENSSL_free(tmp); + } + } + } + } while (!ok); + } + X509_free(peer); + if (!ok) + { soap_set_sender_error(soap, "SSL/TLS error", "SSL/TLS certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + } + } +#endif +#ifdef WITH_GNUTLS + soap->ssl_flags |= SOAP_SSL_CLIENT; + if (!soap->session && (soap->error = soap->fsslauth(soap))) + { soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + gnutls_transport_set_ptr(soap->session, (gnutls_transport_ptr_t)(long)fd); + /* Set SSL sockets to non-blocking */ + if (soap->connect_timeout) + { SOAP_SOCKNONBLOCK(fd) + retries = 10*soap->connect_timeout; + } + else + SOAP_SOCKBLOCK(fd) + if (retries <= 0) + retries = 100; /* timeout: 10 sec retries, 100 times 0.1 sec */ + while ((r = gnutls_handshake(soap->session))) + { int s; + /* GNUTLS repeat handhake when GNUTLS_E_AGAIN */ + if (retries-- <= 0) + break; + if (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED) + { if (!gnutls_record_get_direction(soap->session)) + s = tcp_select(soap, fd, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000); + else + s = tcp_select(soap, fd, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, -100000); + if (s < 0 && soap->errnum != SOAP_EINTR) + break; + } + else + { soap->errnum = soap_socket_errno(fd); + break; + } + } + if (r) + { soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL/TLS handshake failed", SOAP_SSL_ERROR); + soap->fclosesocket(soap, fd); + return SOAP_INVALID_SOCKET; + } + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION)) + { const char *err = ssl_verify(soap, host); + if (err) + { soap->fclosesocket(soap, fd); + soap->error = soap_set_sender_error(soap, "SSL/TLS error", err, SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + } +#endif +#else + soap->fclosesocket(soap, fd); + soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; +#endif + } + if (soap->recv_timeout || soap->send_timeout) + SOAP_SOCKNONBLOCK(fd) + else + SOAP_SOCKBLOCK(fd) + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout) +{ register int r; + struct timeval tv; + fd_set fd[3], *rfd, *sfd, *efd; + soap->errnum = 0; +#ifndef WIN32 + /* if fd max set size exceeded, use poll() when available */ +#if defined(__QNX__) || defined(QNX) /* select() is not MT safe on some QNX */ + if (1) +#else + if ((int)s >= (int)FD_SETSIZE) +#endif +#ifdef HAVE_POLL + { struct pollfd pollfd; + int retries = 0; + pollfd.fd = (int)s; + pollfd.events = 0; + if (flags & SOAP_TCP_SELECT_RCV) + pollfd.events |= POLLIN; + if (flags & SOAP_TCP_SELECT_SND) + pollfd.events |= POLLOUT; + if (flags & SOAP_TCP_SELECT_ERR) + pollfd.events |= POLLERR; + if (timeout < 0) + timeout /= -1000; /* -usec -> ms */ + else if (timeout <= 1000000) /* avoid overflow */ + timeout *= 1000; /* sec -> ms */ + else + { retries = timeout / 1000000; + timeout = 1000000000; + } + do r = poll(&pollfd, 1, timeout); + while (r == 0 && retries--); + if (r > 0) + { r = 0; + if ((flags & SOAP_TCP_SELECT_RCV) && (pollfd.revents & POLLIN)) + r |= SOAP_TCP_SELECT_RCV; + if ((flags & SOAP_TCP_SELECT_SND) && (pollfd.revents & POLLOUT)) + r |= SOAP_TCP_SELECT_SND; + if ((flags & SOAP_TCP_SELECT_ERR) && (pollfd.revents & POLLERR)) + r |= SOAP_TCP_SELECT_ERR; + } + else if (r < 0) + soap->errnum = soap_socket_errno(s); + return r; + } +#else + { soap->error = SOAP_FD_EXCEEDED; + return -1; + } +#endif +#endif + rfd = sfd = efd = NULL; + if (flags & SOAP_TCP_SELECT_RCV) + { rfd = &fd[0]; + FD_ZERO(rfd); + FD_SET(s, rfd); + } + if (flags & SOAP_TCP_SELECT_SND) + { sfd = &fd[1]; + FD_ZERO(sfd); + FD_SET(s, sfd); + } + if (flags & SOAP_TCP_SELECT_ERR) + { efd = &fd[2]; + FD_ZERO(efd); + FD_SET(s, efd); + } + if (timeout >= 0) + { tv.tv_sec = timeout; + tv.tv_usec = 0; + } + else + { tv.tv_sec = -timeout / 1000000; + tv.tv_usec = -timeout % 1000000; + } + r = select((int)s + 1, rfd, sfd, efd, &tv); + if (r > 0) + { r = 0; + if ((flags & SOAP_TCP_SELECT_RCV) && FD_ISSET(s, rfd)) + r |= SOAP_TCP_SELECT_RCV; + if ((flags & SOAP_TCP_SELECT_SND) && FD_ISSET(s, sfd)) + r |= SOAP_TCP_SELECT_SND; + if ((flags & SOAP_TCP_SELECT_ERR) && FD_ISSET(s, efd)) + r |= SOAP_TCP_SELECT_ERR; + } + else if (r < 0) + soap->errnum = soap_socket_errno(s); + return r; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static SOAP_SOCKET +tcp_accept(struct soap *soap, SOAP_SOCKET s, struct sockaddr *a, int *n) +{ SOAP_SOCKET fd; + fd = accept(s, a, (SOAP_SOCKLEN_T*)n); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif +#endif + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_disconnect(struct soap *soap) +{ +#ifdef WITH_OPENSSL + if (soap->ssl) + { int r, s = 0; + if (soap->session) + { SSL_SESSION_free(soap->session); + soap->session = NULL; + } + if (*soap->host) + { soap->session = SSL_get1_session(soap->ssl); + if (soap->session) + { strcpy(soap->session_host, soap->host); + soap->session_port = soap->port; + } + } + r = SSL_shutdown(soap->ssl); + /* SSL shutdown does not work when reads are pending */ + while (SSL_want_read(soap->ssl)) + { SSL_read(soap->ssl, NULL, 0); + if (soap_socket_errno(soap->socket) != SOAP_EAGAIN) + { r = SSL_shutdown(soap->ssl); + break; + } + } + if (r == 0) + { if (soap_valid_socket(soap->socket)) + { if (!soap->fshutdownsocket(soap, soap->socket, SOAP_SHUT_WR)) + { +#ifndef WITH_LEAN + /* + wait up to 10 seconds for close_notify to be sent by peer (if peer not + present, this avoids calling SSL_shutdown() which has a lengthy return + timeout) + */ + r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, 10); + if (r <= 0 && soap->errnum != SOAP_EINTR) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connection lost...\n")); + soap->fclosesocket(soap, soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + ERR_remove_state(0); + return SOAP_OK; + } +#else + r = SSL_shutdown(soap->ssl); +#endif + } + } + } + if (r != 1) + { s = ERR_get_error(); + if (s) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r))); + if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP)) + { soap->fclosesocket(soap, soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + } + } + } + SSL_free(soap->ssl); + soap->ssl = NULL; + if (s) + return SOAP_SSL_ERROR; + ERR_remove_state(0); + } +#endif +#ifdef WITH_GNUTLS + if (soap->session) + { gnutls_bye(soap->session, GNUTLS_SHUT_RDWR); + gnutls_deinit(soap->session); + soap->session = NULL; + } +#endif + if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP)) + { soap->fshutdownsocket(soap, soap->socket, SOAP_SHUT_RDWR); + soap->fclosesocket(soap, soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_closesocket(struct soap *soap, SOAP_SOCKET fd) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd)); + return soap_closesocket(fd); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how)); + return shutdown(fd, how); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +SOAP_SOCKET +SOAP_FMAC2 +soap_bind(struct soap *soap, const char *host, int port, int backlog) +{ +#ifdef WITH_IPV6 + struct addrinfo *addrinfo = NULL; + struct addrinfo hints; + struct addrinfo res; + int err; +#ifdef WITH_NO_IPV6_V6ONLY + int unset = 0; +#endif +#endif +#ifndef WITH_LEAN +#ifndef WITH_WIN32 + int len = SOAP_BUFLEN; +#else + int len = SOAP_BUFLEN + 1; /* speeds up windows xfer */ +#endif + int set = 1; +#endif + if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, soap->master); + soap->master = SOAP_INVALID_SOCKET; + } + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 1; + if (tcp_init(soap)) + { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + hints.ai_socktype = SOCK_DGRAM; + else +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + soap->errmode = 2; + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo); + if (err || !addrinfo) + { soap_set_receiver_error(soap, SOAP_GAI_STRERROR(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + res = *addrinfo; + memcpy(&soap->peer, addrinfo->ai_addr, addrinfo->ai_addrlen); + soap->peerlen = addrinfo->ai_addrlen; + res.ai_addr = (struct sockaddr*)&soap->peer; + res.ai_addrlen = soap->peerlen; + freeaddrinfo(addrinfo); + soap->master = (int)socket(res.ai_family, res.ai_socktype, res.ai_protocol); +#else +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0); + else +#endif + soap->master = (int)socket(AF_INET, SOCK_STREAM, 0); +#endif + soap->errmode = 0; + if (!soap_valid_socket(soap->master)) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + soap->socket = soap->master; +#endif +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(soap->master, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->bind_flags && setsockopt(soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt(soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt(soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif +#endif +#ifdef WITH_IPV6 +#ifdef WITH_IPV6_V6ONLY + if (setsockopt(soap->master, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt IPV6_V6ONLY failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif +#ifdef WITH_NO_IPV6_V6ONLY + if (setsockopt(soap->master, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&unset, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt IPV6_V6ONLY failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif + soap->errmode = 0; + if (bind(soap->master, res.ai_addr, (int)res.ai_addrlen)) + { soap->errnum = soap_socket_errno(soap->master); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#else + soap->peerlen = sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->peer.sin_family = AF_INET; + soap->errmode = 2; + if (host) + { if (soap->fresolve(soap, host, &soap->peer.sin_addr)) + { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + else + soap->peer.sin_addr.s_addr = htonl(INADDR_ANY); + soap->peer.sin_port = htons((short)port); + soap->errmode = 0; + if (bind(soap->master, (struct sockaddr*)&soap->peer, (int)soap->peerlen)) + { soap->errnum = soap_socket_errno(soap->master); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif + if (!(soap->omode & SOAP_IO_UDP) && listen(soap->master, backlog)) + { soap->errnum = soap_socket_errno(soap->master); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + return soap->master; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_poll(struct soap *soap) +{ +#ifndef WITH_LEAN + register int r; + if (soap_valid_socket(soap->socket)) + { r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, 0); + if (r > 0 && (r & SOAP_TCP_SELECT_ERR)) + r = -1; + } + else if (soap_valid_socket(soap->master)) + r = tcp_select(soap, soap->master, SOAP_TCP_SELECT_SND, 0); + else + return SOAP_OK; /* OK when no socket! */ + if (r > 0) + { +#ifdef WITH_OPENSSL + if (soap->imode & SOAP_ENC_SSL) + { + if (soap_valid_socket(soap->socket) + && (r & SOAP_TCP_SELECT_SND) + && (!(r & SOAP_TCP_SELECT_RCV) + || SSL_peek(soap->ssl, soap->tmpbuf, 1) > 0)) + return SOAP_OK; + } + else +#endif + if (soap_valid_socket(soap->socket) + && (r & SOAP_TCP_SELECT_SND) + && (!(r & SOAP_TCP_SELECT_RCV) + || recv(soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0)) + return SOAP_OK; + } + else if (r < 0) + { if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno(soap->master) != SOAP_EINTR) + { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR); + return soap->error = SOAP_TCP_ERROR; + } + } + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r)); + return SOAP_EOF; +#else + return SOAP_OK; +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +SOAP_SOCKET +SOAP_FMAC2 +soap_accept(struct soap *soap) +{ int n = (int)sizeof(soap->peer); +#ifndef WITH_LEAN +#ifndef WITH_WIN32 + int len = SOAP_BUFLEN; +#else + int len = SOAP_BUFLEN + 1; /* speeds up windows xfer */ +#endif + int set = 1; +#endif + soap->error = SOAP_OK; +#ifndef WITH_LEAN + if ((soap->omode & SOAP_IO_UDP)) + return soap->socket = soap->master; +#endif + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 0; + soap->keep_alive = 0; + if (soap_valid_socket(soap->master)) + { register int err; + for (;;) + { if (soap->accept_timeout || soap->send_timeout || soap->recv_timeout) + { for (;;) + { register int r; + r = tcp_select(soap, soap->master, SOAP_TCP_SELECT_ALL, soap->accept_timeout ? soap->accept_timeout : 60); + if (r > 0) + break; + if (!r && soap->accept_timeout) + { soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (r < 0) + { r = soap->errnum; + if (r != SOAP_EINTR) + { soap_closesock(soap); + soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + } + } + if (soap->accept_timeout) + SOAP_SOCKNONBLOCK(soap->master) + else + SOAP_SOCKBLOCK(soap->master) + soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n); + soap->peerlen = (size_t)n; + if (soap_valid_socket(soap->socket)) + { +#ifdef WITH_IPV6 +/* Use soap->host to store the numeric form of the remote host */ + getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host)); + soap->ip = 0; /* info stored in soap->peer and soap->host */ + soap->port = 0; /* info stored in soap->peer and soap->host */ +#else + soap->ip = ntohl(soap->peer.sin_addr.s_addr); + soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %d.%d.%d.%d\n", soap->socket, soap->port, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF)); +#endif +#ifndef WITH_LEAN + if (soap->accept_flags == SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = soap->linger_time; + if (setsockopt(soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + } + else if (soap->accept_flags && setsockopt(soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } +#endif +#endif + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + if (soap->send_timeout || soap->recv_timeout) + SOAP_SOCKNONBLOCK(soap->socket) + else + SOAP_SOCKBLOCK(soap->socket) + return soap->socket; + } + err = soap_socket_errno(soap->socket); + if (err != 0 && err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host)); + soap->errnum = err; + soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + } + } + else + { soap->errnum = 0; + soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_closesock(struct soap *soap) +{ register int status = soap->error; +#ifndef WITH_LEANER + if (status) /* close on error: attachment state is not to be trusted */ + { soap->mime.first = NULL; + soap->mime.last = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + } +#endif + if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap))) + return soap->error; + if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive) + { if (soap->fclose && (soap->error = soap->fclose(soap))) + return soap->error; + soap->keep_alive = 0; + } +#ifdef WITH_ZLIB + if (soap->zlib_state == SOAP_ZLIB_DEFLATE) + deflateEnd(soap->d_stream); + else if (soap->zlib_state == SOAP_ZLIB_INFLATE) + inflateEnd(soap->d_stream); + soap->zlib_state = SOAP_ZLIB_NONE; +#endif + return soap->error = status; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_cleanup(struct soap *soap) +{ soap_done(soap); +#ifdef WIN32 + if (!tcp_done) + return; + tcp_done = 0; + WSACleanup(); +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_done(struct soap *soap) +{ +#ifdef SOAP_DEBUG + int i; +#endif + if (soap_check_state(soap)) + return; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Done with context\n")); + soap_free_temp(soap); + while (soap->clist) + { struct soap_clist *p = soap->clist->next; + SOAP_FREE(soap, soap->clist); + soap->clist = p; + } + if (soap->state == SOAP_INIT) + soap->omode &= ~SOAP_IO_UDP; /* to force close the socket */ + soap->keep_alive = 0; /* to force close the socket */ + soap_closesock(soap); +#ifdef WITH_COOKIES + soap_free_cookies(soap); +#endif + while (soap->plugins) + { register struct soap_plugin *p = soap->plugins->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id)); + if (soap->plugins->fcopy || soap->state == SOAP_INIT) + soap->plugins->fdelete(soap, soap->plugins); + SOAP_FREE(soap, soap->plugins); + soap->plugins = p; + } + soap->fplugin = fplugin; + soap->fmalloc = NULL; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fput = http_put; + soap->fget = http_get; + soap->fdel = http_405; + soap->fopt = http_405; + soap->fhead = http_405; + soap->fform = NULL; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif + soap->fheader = NULL; +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif +#ifndef WITH_LEANER + soap->fprepareinitsend = NULL; + soap->fprepareinitrecv = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; + soap->fpreparefinalsend = NULL; + soap->fpreparefinalrecv = NULL; +#endif + soap->fseterror = NULL; + soap->fignore = NULL; + soap->fserveloop = NULL; +#ifdef WITH_OPENSSL + if (soap->session) + { SSL_SESSION_free(soap->session); + soap->session = NULL; + } +#endif + if (soap->state == SOAP_INIT) + { if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, soap->master); + soap->master = SOAP_INVALID_SOCKET; + } + } +#ifdef WITH_OPENSSL + if (soap->ssl) + { SSL_free(soap->ssl); + soap->ssl = NULL; + } + if (soap->state == SOAP_INIT) + { if (soap->ctx) + { SSL_CTX_free(soap->ctx); + soap->ctx = NULL; + } + } + ERR_remove_state(0); +#endif +#ifdef WITH_GNUTLS + if (soap->state == SOAP_INIT) + { if (soap->xcred) + { gnutls_certificate_free_credentials(soap->xcred); + soap->xcred = NULL; + } + if (soap->acred) + { gnutls_anon_free_client_credentials(soap->acred); + soap->acred = NULL; + } + if (soap->cache) + { gnutls_priority_deinit(soap->cache); + soap->cache = NULL; + } + if (soap->dh_params) + { gnutls_dh_params_deinit(soap->dh_params); + soap->dh_params = NULL; + } + if (soap->rsa_params) + { gnutls_rsa_params_deinit(soap->rsa_params); + soap->rsa_params = NULL; + } + } + if (soap->session) + { gnutls_deinit(soap->session); + soap->session = NULL; + } +#endif +#ifdef WITH_C_LOCALE + freelocale(soap->c_locale); +#endif +#ifdef WITH_ZLIB + if (soap->d_stream) + { SOAP_FREE(soap, (void*)soap->d_stream); + soap->d_stream = NULL; + } + if (soap->z_buf) + { SOAP_FREE(soap, (void*)soap->z_buf); + soap->z_buf = NULL; + } +#endif +#ifdef SOAP_DEBUG + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n")); + for (i = 0; i < SOAP_MAXLOGS; i++) + { if (soap->logfile[i]) + { SOAP_FREE(soap, (void*)soap->logfile[i]); + soap->logfile[i] = NULL; + } + soap_close_logfile(soap, i); + } + soap->state = SOAP_NONE; +#endif +#ifdef SOAP_MEM_DEBUG + soap_free_mht(soap); +#endif +} +#endif + +/******************************************************************************\ + * + * HTTP + * +\******************************************************************************/ + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +int +http_parse(struct soap *soap) +{ char header[SOAP_HDRLEN], *s; + unsigned short httpcmd = 0, status = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n")); + *soap->endpoint = '\0'; + soap->length = 0; + soap->userid = NULL; + soap->passwd = NULL; + soap->action = NULL; + soap->authrealm = NULL; + soap->proxy_from = NULL; + soap->http_content = NULL; + soap->status = 0; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + { if (soap->error == SOAP_EOF) + return SOAP_EOF; + return soap->error = 414; + } + if ((s = strchr(soap->msgbuf, ' '))) + { soap->status = (unsigned short)soap_strtoul(s, &s, 10); + if (!soap_blank((soap_wchar)*s)) + soap->status = 0; + } + else + soap->status = 0; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf)); + for (;;) + { if (soap_getline(soap, header, SOAP_HDRLEN)) + { if (soap->error == SOAP_EOF) + { soap->error = SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n")); + break; + } + return soap->error; + } + if (!*header) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP header: %s\n", header)); + s = strchr(header, ':'); + if (s) + { char *t; + *s = '\0'; + do s++; + while (*s && *s <= 32); + if (*s == '"') + s++; + t = s + strlen(s) - 1; + while (t > s && *t <= 32) + t--; + if (t >= s && *t == '"') + t--; + t[1] = '\0'; + if ((soap->error = soap->fparsehdr(soap, header, s))) + { if (soap->error < SOAP_STOP) + return soap->error; + status = soap->error; + soap->error = SOAP_OK; + } + } + } + } while (soap->status == 100); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing, status = %d\n", soap->status)); + s = strstr(soap->msgbuf, "HTTP/"); + if (s && s[7] != '1') + { if (soap->keep_alive == 1) + soap->keep_alive = 0; + if (soap->status == 0 && (soap->omode & SOAP_IO) == SOAP_IO_CHUNK) /* soap->status == 0 for HTTP request */ + { soap->imode |= SOAP_IO_CHUNK; + soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE; + } + } + if (soap->keep_alive < 0) + soap->keep_alive = 1; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive)); + if (soap->status == 0) + { size_t l = 0; + if (s) + { if (!strncmp(soap->msgbuf, "POST ", l = 5)) + httpcmd = 1; + else if (!strncmp(soap->msgbuf, "PUT ", l = 4)) + httpcmd = 2; + else if (!strncmp(soap->msgbuf, "GET ", l = 4)) + httpcmd = 3; + else if (!strncmp(soap->msgbuf, "DELETE ", l = 7)) + httpcmd = 4; + else if (!strncmp(soap->msgbuf, "OPTIONS ", l = 8)) + httpcmd = 5; + else if (!strncmp(soap->msgbuf, "HEAD ", l = 5)) + httpcmd = 6; + } + if (s && httpcmd) + { size_t m = strlen(soap->endpoint); + size_t n = m + (s - soap->msgbuf) - l - 1; + if (m > n) + m = n; + if (n >= sizeof(soap->endpoint)) + n = sizeof(soap->endpoint) - 1; + strncpy(soap->path, soap->msgbuf + l, n - m); + soap->path[n - m] = '\0'; + strcat(soap->endpoint, soap->path); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint)); + if (httpcmd > 1) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP %s handler\n", soap->msgbuf)); + switch (httpcmd) + { case 2: soap->error = soap->fput(soap); break; + case 3: soap->error = soap->fget(soap); break; + case 4: soap->error = soap->fdel(soap); break; + case 5: soap->error = soap->fopt(soap); break; + case 6: soap->error = soap->fhead(soap); break; + default: soap->error = 405; break; + } + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP handler return = %d\n", soap->error)); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + return soap->error; + } + if (status) + return soap->error = status; + } + else if (status) + return soap->error = status; + else if (s) + return soap->error = 405; + } + /* Status OK (HTTP 200) */ + if (soap->status == 0 || soap->status == 200) + return SOAP_OK; + /* Status 201 (Created), 202 (Accepted), ... and HTTP 400 and 500 errors + may not have a body. When content length, content type, or chunking is + used assume there is a message to parse, either XML or HTTP. + */ + if (soap->length > 0 || (soap->http_content && soap->recv_timeout) || (soap->imode & SOAP_IO) == SOAP_IO_CHUNK) + { if (((soap->status > 200 && soap->status <= 299) || soap->status == 400 || soap->status == 500)) + return SOAP_OK; + /* force close afterwards in soap_closesock() */ + soap->keep_alive = 0; +#ifndef WITH_LEAN + /* read HTTP body for error details */ + s = soap_get_http_body(soap); + if (s) + return soap_set_receiver_error(soap, soap->msgbuf, s, soap->status); +#endif + } + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP error %d\n", soap->status)); + return soap_set_receiver_error(soap, "HTTP Error", soap->msgbuf, soap->status); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse_header(struct soap *soap, const char *key, const char *val) +{ if (!soap_tag_cmp(key, "Host")) + { +#if defined(WITH_OPENSSL) || defined(WITH_GNUTLS) + if (soap->imode & SOAP_ENC_SSL) + strcpy(soap->endpoint, "https://"); + else +#endif + strcpy(soap->endpoint, "http://"); + strncat(soap->endpoint, val, sizeof(soap->endpoint) - 8); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifndef WITH_LEANER + else if (!soap_tag_cmp(key, "Content-Type")) + { const char *action; + soap->http_content = soap_strdup(soap, val); + if (soap_get_header_attribute(soap, val, "application/dime")) + soap->imode |= SOAP_ENC_DIME; + else if (soap_get_header_attribute(soap, val, "multipart/related") + || soap_get_header_attribute(soap, val, "multipart/form-data")) + { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary")); + soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start")); + soap->imode |= SOAP_ENC_MIME; + } + action = soap_get_header_attribute(soap, val, "action"); + if (action) + { if (*action == '"') + { soap->action = soap_strdup(soap, action + 1); + soap->action[strlen(soap->action) - 1] = '\0'; + } + else + soap->action = soap_strdup(soap, action); + } + } +#endif + else if (!soap_tag_cmp(key, "Content-Length")) + { soap->length = soap_strtoul(val, NULL, 10); + } + else if (!soap_tag_cmp(key, "Content-Encoding")) + { if (!soap_tag_cmp(val, "deflate")) +#ifdef WITH_ZLIB + soap->zlib_in = SOAP_ZLIB_DEFLATE; +#else + return SOAP_ZLIB_ERROR; +#endif + else if (!soap_tag_cmp(val, "gzip")) +#ifdef WITH_GZIP + soap->zlib_in = SOAP_ZLIB_GZIP; +#else + return SOAP_ZLIB_ERROR; +#endif + } +#ifdef WITH_ZLIB + else if (!soap_tag_cmp(key, "Accept-Encoding")) + { +#ifdef WITH_GZIP + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "gzip")) + soap->zlib_out = SOAP_ZLIB_GZIP; + else +#endif + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "deflate")) + soap->zlib_out = SOAP_ZLIB_DEFLATE; + else + soap->zlib_out = SOAP_ZLIB_NONE; + } +#endif + else if (!soap_tag_cmp(key, "Transfer-Encoding")) + { soap->imode &= ~SOAP_IO; + if (!soap_tag_cmp(val, "chunked")) + soap->imode |= SOAP_IO_CHUNK; + } + else if (!soap_tag_cmp(key, "Connection")) + { if (!soap_tag_cmp(val, "keep-alive")) + soap->keep_alive = -soap->keep_alive; + else if (!soap_tag_cmp(val, "close")) + soap->keep_alive = 0; + } +#ifndef WITH_LEAN + else if (!soap_tag_cmp(key, "Authorization")) + { if (!soap_tag_cmp(val, "Basic *")) + { int n; + char *s; + soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n); + soap->tmpbuf[n] = '\0'; + if ((s = strchr(soap->tmpbuf, ':'))) + { *s = '\0'; + soap->userid = soap_strdup(soap, soap->tmpbuf); + soap->passwd = soap_strdup(soap, s + 1); + } + } + } + else if (!soap_tag_cmp(key, "WWW-Authenticate")) + { soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm")); + } + else if (!soap_tag_cmp(key, "Expect")) + { if (!soap_tag_cmp(val, "100-continue")) + { if ((soap->error = soap->fposthdr(soap, "HTTP/1.1 100 Continue", NULL)) + || (soap->error = soap->fposthdr(soap, NULL, NULL))) + return soap->error; + } + } +#endif + else if (!soap_tag_cmp(key, "SOAPAction")) + { if (*val == '"') + { soap->action = soap_strdup(soap, val + 1); + soap->action[strlen(soap->action) - 1] = '\0'; + } + else + soap->action = soap_strdup(soap, val); + } + else if (!soap_tag_cmp(key, "Location")) + { strncpy(soap->endpoint, val, sizeof(soap->endpoint)); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } + else if (!soap_tag_cmp(key, "X-Forwarded-For")) + { soap->proxy_from = soap_strdup(soap, val); + } +#ifdef WITH_COOKIES + else if (!soap_tag_cmp(key, "Cookie") + || !soap_tag_cmp(key, "Cookie2") + || !soap_tag_cmp(key, "Set-Cookie") + || !soap_tag_cmp(key, "Set-Cookie2")) + { soap_getcookies(soap, val); + } +#endif + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_get_header_attribute(struct soap *soap, const char *line, const char *key) +{ register const char *s = line; + if (s) + { while (*s) + { register short flag; + s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s); + flag = soap_tag_cmp(soap->tmpbuf, key); + s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s); + if (!flag) + return soap->tmpbuf; + } + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_key(char *buf, size_t len, const char *val) +{ return soap_decode(buf, len, val, "=,;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_val(char *buf, size_t len, const char *val) +{ if (*val != '=') + { *buf = '\0'; + return val; + } + return soap_decode(buf, len, val + 1, ",;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +static const char* +soap_decode(char *buf, size_t len, const char *val, const char *sep) +{ const char *s; + char *t = buf; + for (s = val; *s; s++) + if (*s != ' ' && *s != '\t' && !strchr(sep, *s)) + break; + if (*s == '"') + { s++; + while (*s && *s != '"' && --len) + *t++ = *s++; + } + else + { while (*s && !soap_blank((soap_wchar)*s) && !strchr(sep, *s) && --len) + { if (*s == '%') + { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4) + + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0'); + s += 3; + } + else + *t++ = *s++; + } + } + *t = '\0'; + while (*s && !strchr(sep, *s)) + s++; + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static const char* +http_error(struct soap *soap, int status) +{ register const char *msg = SOAP_STR_EOS; +#ifndef WITH_LEAN + msg = soap_code_str(h_http_error_codes, status); + if (!msg) + msg = SOAP_STR_EOS; +#endif + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_put(struct soap *soap) +{ return http_parse(soap); +} +#endif +#endif +/******************************************************************************/ + +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_get(struct soap *soap) +{ return SOAP_GET_METHOD; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_405(struct soap *soap) +{ return 405; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count) +{ register const char *s; + register int err; + if (soap->status == SOAP_GET) + s = "GET"; + else + s = "POST"; +#ifdef PALM + if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8)) +#else + if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6))) +#endif + return SOAP_OK; + if (strlen(endpoint) + strlen(soap->http_version) > sizeof(soap->tmpbuf) - 80) + return soap->error = SOAP_EOM; + if (soap->proxy_host && soap_tag_cmp(endpoint, "https:*")) + sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version); + else + sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; +#ifdef WITH_OPENSSL + if ((soap->ssl && soap->port != 443) || (!soap->ssl && soap->port != 80)) + sprintf(soap->tmpbuf, "%s:%d", host, port); + else + strcpy(soap->tmpbuf, host); +#else + if (port != 80) + sprintf(soap->tmpbuf, "%s:%d", host, port); + else + strcpy(soap->tmpbuf, host); +#endif + if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf)) + || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, SOAP_OK, count))) + return err; +#ifdef WITH_ZLIB +#ifdef WITH_GZIP + if ((err = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate"))) +#else + if ((err = soap->fposthdr(soap, "Accept-Encoding", "deflate"))) +#endif + return err; +#endif +#ifndef WITH_LEAN + if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf))) + return err; + } + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + return err; + } +#endif +#ifdef WITH_COOKIES +#ifdef WITH_OPENSSL + if (soap_putcookies(soap, host, path, soap->ssl != NULL)) + return soap->error; +#else + if (soap_putcookies(soap, host, path, 0)) + return soap->error; +#endif +#endif + if (soap->status != SOAP_GET && (soap->version == 1 || (action && *action))) + { sprintf(soap->tmpbuf, "\"%s\"", action && strlen(action) < sizeof(soap->tmpbuf) - 3 ? action : SOAP_STR_EOS); + if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf))) + return err; + } + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_send_header(struct soap *soap, const char *s) +{ register const char *t; + do + { t = strchr(s, '\n'); /* disallow \n in HTTP headers */ + if (!t) + t = s + strlen(s); + if (soap_send_raw(soap, s, t - s)) + return soap->error; + s = t + 1; + } while (*t); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post_header(struct soap *soap, const char *key, const char *val) +{ if (key) + { if (http_send_header(soap, key)) + return soap->error; + if (val && (soap_send_raw(soap, ": ", 2) || http_send_header(soap, val))) + return soap->error; + } + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_response(struct soap *soap, int status, size_t count) +{ register int err; +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + httpOutputEnable(soap->rpmreqid); +#endif + if (strlen(soap->http_version) > 4) + return soap->error = SOAP_EOM; + if (!status || status == SOAP_HTML || status == SOAP_FILE) + { const char *s; + if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)) + s = "200 OK"; + else + s = "202 ACCEPTED"; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s)); +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application (socket) or CGI (stdin/out)? */ +#endif + { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI header */ + return err; + } + else if (status >= 200 && status < 600) + { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status)); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; +#ifndef WITH_LEAN + if (status == 401) + { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", (soap->authrealm && strlen(soap->authrealm) < sizeof(soap->tmpbuf) - 14) ? soap->authrealm : "gSOAP Web Service"); + if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf))) + return err; + } + else if ((status >= 301 && status <= 303) || status == 307) + { if ((err = soap->fposthdr(soap, "Location", soap->endpoint))) + return err; + } +#endif + } + else + { const char *s = *soap_faultcode(soap); + if (status >= SOAP_GET_METHOD && status <= SOAP_HTTP_METHOD) + s = "405 Method Not Allowed"; + else if (soap->version == 2 && (!s || !strcmp(s, "SOAP-ENV:Sender"))) + s = "400 Bad Request"; + else + s = "500 Internal Server Error"; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status)); +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +#endif + { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI */ + return err; + } + if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, status, count))) + return err; +#ifdef WITH_COOKIES + if (soap_putsetcookies(soap)) + return soap->error; +#endif + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_response(struct soap *soap, int status) +{ register size_t count; + if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */)) + && (status == SOAP_HTML || status == SOAP_FILE)) + soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE; + soap->status = status; + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML)) + { register int n = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((n & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fresponse(soap, status, count))) + return soap->error; +#ifndef WITH_LEANER + if ((n & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = n; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************\ + * + * HTTP Cookies + * +\******************************************************************************/ + +#ifdef WITH_COOKIES +/******************************************************************************/ +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_encode_cookie(const char *s, char *t, size_t len) +{ register int c; + register size_t n = len; + while ((c = *s++) && --n > 0) + { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}#!$&'*+", c)) + *t++ = c; + else if (n > 2) + { *t++ = '%'; + *t++ = (c >> 4) + (c > 159 ? '7' : '0'); + c &= 0xF; + *t++ = c + (c > 9 ? '7' : '0'); + n -= 2; + } + else + break; + } + *t = '\0'; + return len - n; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (!path) + path = SOAP_STR_EOS; + else if (*path == '/') + path++; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Search cookie %s domain=%s path=%s\n", name, domain?domain:"(null)", path?path:"(null)")); + for (p = soap->cookies; p; p = p->next) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie in database: %s=%s domain=%s path=%s env=%hd\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->env)); + if (!strcmp(p->name, name) + && p->domain + && p->path + && !strcmp(p->domain, domain) + && (!*p->path || !strncmp(p->path, path, strlen(p->path)))) + break; + } + return p; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + int n; + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (!path) + path = SOAP_STR_EOS; + else if (*path == '/') + path++; + q = soap_cookie(soap, name, domain, path); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set %scookie: %s=%s domain=%s path=%s\n", q ? SOAP_STR_EOS : "new ", name, value?value:"(null)", domain?domain:"(null)", path?path:"(null)")); + if (!q) + { if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + { if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1))) + strcpy(q->name, name); + q->value = NULL; + q->domain = NULL; + q->path = NULL; + q->expire = 0; + q->maxage = -1; + q->version = 1; + q->secure = 0; + q->modified = 0; + for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--) + if (!strcmp((*p)->name, name) && (*p)->path && path && strcmp((*p)->path, path) < 0) + break; + if (n) + { q->next = *p; + *p = q; + } + else + { SOAP_FREE(soap, q->name); + SOAP_FREE(soap, q); + q = NULL; + } + } + } + else + q->modified = 1; + if (q) + { if (q->value) + { if (!value || strcmp(value, q->value)) + { SOAP_FREE(soap, q->value); + q->value = NULL; + } + } + if (value && *value && !q->value && (q->value = (char*)SOAP_MALLOC(soap, strlen(value)+1))) + strcpy(q->value, value); + if (q->domain) + { if (!domain || strcmp(domain, q->domain)) + { SOAP_FREE(soap, q->domain); + q->domain = NULL; + } + } + if (domain && !q->domain && (q->domain = (char*)SOAP_MALLOC(soap, strlen(domain)+1))) + strcpy(q->domain, domain); + if (q->path) + { if (!path || strncmp(path, q->path, strlen(q->path))) + { SOAP_FREE(soap, q->path); + q->path = NULL; + } + } + if (path && !q->path && (q->path = (char*)SOAP_MALLOC(soap, strlen(path)+1))) + strcpy(q->path, path); + q->session = 1; + q->env = 0; + } + return q; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + if (!domain) + domain = soap->cookie_domain; + if (!domain) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie domain not set\n", name?name:"(null)")); + return; + } + if (!path) + path = soap->cookie_path; + if (!path) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie path not set\n", name?name:"(null)")); + return; + } + if (*path == '/') + path++; + for (p = &soap->cookies, q = *p; q; q = *p) + { if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path))) + { if (q->value) + SOAP_FREE(soap, q->value); + if (q->domain) + SOAP_FREE(soap, q->domain); + if (q->path) + SOAP_FREE(soap, q->path); + *p = q->next; + SOAP_FREE(soap, q); + } + else + p = &q->next; + } +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_env_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path)) && p->env) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +time_t +SOAP_FMAC2 +soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->expire; + return -1; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path) +{ struct soap_cookie *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie expiration max-age %ld: %s domain=%s path=%s\n", expire, name, domain?domain:"(null)", path?path:"(null)")); + if ((p = soap_cookie(soap, name, domain, path))) + { p->maxage = expire; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 1; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 0; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putsetcookies(struct soap *soap) +{ struct soap_cookie *p; + char *s, tmp[4096]; + const char *t; + for (p = soap->cookies; p; p = p->next) + { + if (p->modified +#ifdef WITH_OPENSSL + || (!p->env && !soap->ssl == !p->secure) +#endif + ) + { s = tmp; + if (p->name) + s += soap_encode_cookie(p->name, s, tmp-s+4064); + if (p->value && *p->value) + { *s++ = '='; + s += soap_encode_cookie(p->value, s, tmp-s+4064); + } + if (p->domain && (int)strlen(p->domain) < tmp-s+4064) + { strcpy(s, ";Domain="); + strcat(s, p->domain); + } + else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064) + { strcpy(s, ";Domain="); + strcat(s, soap->cookie_domain); + } + strcat(s, ";Path=/"); + s += strlen(s); + if (p->path) + t = p->path; + else + t = soap->cookie_path; + if (t) + { if (*t == '/') + t++; + if ((int)strlen(t) < tmp-s+4064) + { if (strchr(t, '%')) /* already URL encoded? */ + { strcpy(s, t); + s += strlen(s); + } + else + s += soap_encode_cookie(t, s, tmp-s+4064); + } + } + if (p->version > 0 && s-tmp < 4060) + { sprintf(s, ";Version=%u", p->version); + s += strlen(s); + } + if (p->maxage >= 0 && s-tmp < 4060) + { sprintf(s, ";Max-Age=%ld", p->maxage); + s += strlen(s); + } + if (s-tmp < 4073 + && (p->secure +#ifdef WITH_OPENSSL + || soap->ssl +#endif + )) + strcpy(s, ";Secure"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp)); + if ((soap->error = soap->fposthdr(soap, "Set-Cookie", tmp))) + return soap->error; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure) +{ struct soap_cookie **p, *q; + unsigned int version = 0; + time_t now = time(NULL); + char *s, tmp[4096]; + p = &soap->cookies; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path)); + if (*path == '/') + path++; + while ((q = *p)) + { if (q->expire && now > q->expire) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name)); + SOAP_FREE(soap, q->name); + if (q->value) + SOAP_FREE(soap, q->value); + if (q->domain) + SOAP_FREE(soap, q->domain); + if (q->path) + SOAP_FREE(soap, q->path); + *p = q->next; + SOAP_FREE(soap, q); + } + else + { int flag; + char *t = q->domain; + size_t n = 0; + if (!t) + flag = 1; + else + { const char *r = strchr(t, ':'); + if (r) + n = r - t; + else + n = strlen(t); + flag = !strncmp(t, domain, n); + } + /* domain-level cookies, cannot compile when WITH_NOIO set */ +#ifndef WITH_NOIO + if (!flag) + { struct hostent *hostent = gethostbyname((char*)domain); + if (hostent) + { const char *r = strchr(hostent->h_name, '.'); + if (!r) + r = hostent->h_name; + flag = !strncmp(t, r, n); + } + } +#endif + if (flag + && (!q->path || !strncmp(q->path, path, strlen(q->path))) + && (!q->secure || secure)) + { s = tmp; + if (q->version != version) + { sprintf(s, "$Version=%u;", q->version); + version = q->version; + } + if (q->name) + s += soap_encode_cookie(q->name, s, tmp-s+4080); + if (q->value && *q->value) + { *s++ = '='; + s += soap_encode_cookie(q->value, s, tmp-s+4080); + } + if (q->path && *q->path && (int)strlen(q->path) < tmp-s+4080) + { sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path)); + s += strlen(s); + } + if (q->domain && (int)strlen(q->domain) < tmp-s+4080) + sprintf(s, ";$Domain=\"%s\"", q->domain); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp)); + if ((soap->error = soap->fposthdr(soap, "Cookie", tmp))) + return soap->error; + } + p = &q->next; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_getcookies(struct soap *soap, const char *val) +{ struct soap_cookie *p = NULL, *q; + const char *s; + char *t, tmp[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + char *domain = NULL; + char *path = NULL; + unsigned int version = 0; + time_t now = time(NULL); + if (!val) + return; + s = val; + while (*s) + { s = soap_decode_key(tmp, sizeof(tmp), s); + if (!soap_tag_cmp(tmp, "$Version")) + { if ((s = soap_decode_val(tmp, sizeof(tmp), s))) + { if (p) + p->version = (int)soap_strtol(tmp, NULL, 10); + else + version = (int)soap_strtol(tmp, NULL, 10); + } + } + else if (!soap_tag_cmp(tmp, "$Path")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->path) + SOAP_FREE(soap, p->path); + p->path = t; + } + else + { if (path) + SOAP_FREE(soap, path); + path = t; + } + } + else if (!soap_tag_cmp(tmp, "$Domain")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->domain) + SOAP_FREE(soap, p->domain); + p->domain = t; + } + else + { if (domain) + SOAP_FREE(soap, domain); + domain = t; + } + } + else if (p && !soap_tag_cmp(tmp, "Path")) + { if (p->path) + SOAP_FREE(soap, p->path); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->path = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(p->path, tmp); + } + else + p->path = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Domain")) + { if (p->domain) + SOAP_FREE(soap, p->domain); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->domain = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(p->domain, tmp); + } + else + p->domain = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Version")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->version = (unsigned int)soap_strtoul(tmp, NULL, 10); + } + else if (p && !soap_tag_cmp(tmp, "Max-Age")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->expire = now + soap_strtol(tmp, NULL, 10); + } + else if (p && !soap_tag_cmp(tmp, "Expires")) + { struct tm T; + char a[3]; + static const char mns[] = "anebarprayunulugepctovec"; + s = soap_decode_val(tmp, sizeof(tmp), s); + if (strlen(tmp) > 20) + { memset((void*)&T, 0, sizeof(T)); + a[0] = tmp[4]; + a[1] = tmp[5]; + a[2] = '\0'; + T.tm_mday = (int)soap_strtol(a, NULL, 10); + a[0] = tmp[8]; + a[1] = tmp[9]; + T.tm_mon = (int)(strstr(mns, a) - mns) / 2; + a[0] = tmp[11]; + a[1] = tmp[12]; + T.tm_year = 100 + (int)soap_strtol(a, NULL, 10); + a[0] = tmp[13]; + a[1] = tmp[14]; + T.tm_hour = (int)soap_strtol(a, NULL, 10); + a[0] = tmp[16]; + a[1] = tmp[17]; + T.tm_min = (int)soap_strtol(a, NULL, 10); + a[0] = tmp[19]; + a[1] = tmp[20]; + T.tm_sec = (int)soap_strtol(a, NULL, 10); + p->expire = soap_timegm(&T); + } + } + else if (p && !soap_tag_cmp(tmp, "Secure")) + p->secure = 1; + else + { if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } + if ((p = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + { p->name = (char*)SOAP_MALLOC(soap, strlen(tmp)+1); + strcpy(p->name, tmp); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { p->value = (char*)SOAP_MALLOC(soap, strlen(tmp)+1); + strcpy(p->value, tmp); + } + else + p->value = NULL; + if (domain) + p->domain = domain; + else if (*soap->host) + { p->domain = (char*)SOAP_MALLOC(soap, strlen(soap->host)+1); + strcpy(p->domain, soap->host); + } + else + p->domain = NULL; + if (path) + p->path = path; + else if (soap->path && *soap->path) + { p->path = (char*)SOAP_MALLOC(soap, strlen(soap->path)+1); + strcpy(p->path, soap->path); + } + else + { p->path = (char*)SOAP_MALLOC(soap, 2); + strcpy(p->path, "/"); + } + p->expire = 0; + p->secure = 0; + p->version = version; + } + } + } + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } + if (domain) + SOAP_FREE(soap, domain); + if (path) + SOAP_FREE(soap, path); +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getenv_cookies(struct soap *soap) +{ struct soap_cookie *p; + const char *s; + char key[4096], val[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + if (!(s = getenv("HTTP_COOKIE"))) + return SOAP_ERR; + do + { s = soap_decode_key(key, sizeof(key), s); + s = soap_decode_val(val, sizeof(val), s); + p = soap_set_cookie(soap, key, val, NULL, NULL); + if (p) + p->env = 1; + } while (*s); + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_copy_cookies(struct soap *copy, const struct soap *soap) +{ struct soap_cookie *p, **q, *r; + q = &r; + for (p = soap->cookies; p; p = p->next) + { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(copy, sizeof(struct soap_cookie)))) + return r; + **q = *p; + if (p->name) + { if (((*q)->name = (char*)SOAP_MALLOC(copy, strlen(p->name)+1))) + strcpy((*q)->name, p->name); + } + if (p->value) + { if (((*q)->value = (char*)SOAP_MALLOC(copy, strlen(p->value)+1))) + strcpy((*q)->value, p->value); + } + if (p->domain) + { if (((*q)->domain = (char*)SOAP_MALLOC(copy, strlen(p->domain)+1))) + strcpy((*q)->domain, p->domain); + } + if (p->path) + { if (((*q)->path = (char*)SOAP_MALLOC(copy, strlen(p->path)+1))) + strcpy((*q)->path, p->path); + } + q = &(*q)->next; + } + *q = NULL; + return r; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_cookies(struct soap *soap) +{ struct soap_cookie *p; + for (p = soap->cookies; p; p = soap->cookies) + { soap->cookies = p->next; + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } +} + +/******************************************************************************/ +#endif /* WITH_COOKIES */ + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_hash(register const char *s) +{ register size_t h = 0; + while (*s) + h = 65599*h + *s++; + return h % SOAP_IDHASH; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_pht(struct soap *soap) +{ register int i; + soap->pblk = NULL; + soap->pidx = 0; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new1(soap_mode mode) +{ return soap_new2(mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new() +{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new2(soap_mode imode, soap_mode omode) +{ struct soap *soap = (struct soap*)malloc(sizeof(struct soap)); + if (soap) + soap_init2(soap, imode, omode); + return soap; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free(struct soap *soap) +{ soap_done(soap); + free(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_del(struct soap *soap) +{ free(soap); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_pht(struct soap *soap) +{ register struct soap_pblk *pb, *next; + register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n")); + for (pb = soap->pblk; pb; pb = next) + { next = pb->next; + SOAP_FREE(soap, pb); + } + soap->pblk = NULL; + soap->pidx = 0; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type) +{ register int i; + struct soap_plist *pp; + if (soap->version == 2) + soap->encoding = 1; + if (a) + i = soap_array_pointer_lookup(soap, p, a, n, type, &pp); + else + i = soap_pointer_lookup(soap, p, type, &pp); + if (i) + { if (soap_is_embedded(soap, pp) + || soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + return i; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (p) + { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next) + { if (pp->ptr == p && pp->type == type) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register size_t h; + register struct soap_plist *pp; + if (!soap->pblk || soap->pidx >= SOAP_PTRBLK) + { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk)); + if (!pb) + { soap->error = SOAP_EOM; + return 0; + } + pb->next = soap->pblk; + soap->pblk = pb; + soap->pidx = 0; + } + *ppp = pp = &soap->pblk->plist[soap->pidx++]; + if (a) + h = soap_hash_ptr(a->__ptr); + else + h = soap_hash_ptr(p); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%d\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1)); + pp->next = soap->pht[h]; + pp->type = type; + pp->mark1 = 0; + pp->mark2 = 0; + pp->ptr = p; + pp->array = a; + soap->pht[h] = pp; + pp->id = ++soap->idnum; + return pp->id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (!p || !a->__ptr) + return 0; + for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next) + { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr) + { register int i; + for (i = 0; i < n; i++) + if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i]) + break; + if (i == n) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_count(struct soap *soap) +{ soap_free_ns(soap); +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME)) + soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME; + else +#endif + { soap->mode = soap->omode; + if ((soap->mode & SOAP_IO_UDP)) + soap->mode |= SOAP_ENC_XML; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE + || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML)) +#ifndef WITH_LEANER + && !soap->fpreparesend +#endif + )) + soap->mode &= ~SOAP_IO_LENGTH; + else + soap->mode |= SOAP_IO_LENGTH; + } +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (!(soap->mode & SOAP_ENC_DIME)) + soap->mode &= ~SOAP_IO_LENGTH; + if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME)) + soap->mode |= SOAP_ENC_MIME; + else if (!(soap->mode & SOAP_ENC_MIME)) + soap->mode &= ~SOAP_ENC_MTOM; + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); + soap->dime.list = soap->dime.last; /* keep track of last DIME attachment */ +#endif + soap->count = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->part = SOAP_BEGIN; + soap->idnum = 0; + soap_clr_attr(soap); + soap_set_local_namespaces(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, (unsigned int)soap->mode, (unsigned long)soap->count)); +#ifndef WITH_LEANER + soap->dime.count = 0; /* count # of attachments */ + soap->dime.size = 0; /* accumulate total size of attachments */ + if (soap->fprepareinitsend && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->error = soap->fprepareinitsend(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_count(struct soap *soap) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n")); +#ifndef WITH_LEANER + if (soap->fpreparefinalsend && (soap->mode & SOAP_IO_LENGTH)) + return soap->error = soap->fpreparefinalsend(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_send(struct soap *soap) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for output\n")); + soap_free_ns(soap); + soap->error = SOAP_OK; + soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME)); +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif +#ifndef WITH_LEAN + if ((soap->mode & SOAP_IO_UDP)) + { soap->mode |= SOAP_ENC_XML; + if (soap->count > SOAP_BUFLEN) + return soap->error = SOAP_UDP_ERROR; + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket)) + { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML)) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } + soap->mode &= ~SOAP_IO_LENGTH; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + if (soap_new_block(soap) == NULL) + return soap->error; + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME)) + { soap->mode |= SOAP_ENC_MIME; + soap->mode &= ~SOAP_ENC_DIME; + } + else if (!(soap->mode & SOAP_ENC_MIME)) + soap->mode &= ~SOAP_ENC_MTOM; + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */ +#ifdef __BORLANDC__ + setmode(soap->sendfd, _O_BINARY); +#else + _setmode(soap->sendfd, _O_BINARY); +#endif +#endif +#endif +#endif +#endif + if (soap->mode & SOAP_IO) + { soap->bufidx = 0; + soap->buflen = 0; + } + soap->chunksize = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->idnum = 0; + soap->level = 0; + soap_clr_attr(soap); + soap_set_local_namespaces(soap); +#ifdef WITH_ZLIB + soap->z_ratio_out = 1.0; + if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE) + { if (!soap->z_buf) + soap->z_buf = (char*)SOAP_MALLOC(soap, SOAP_BUFLEN); + soap->d_stream->next_out = (Byte*)soap->z_buf; + soap->d_stream->avail_out = SOAP_BUFLEN; +#ifdef WITH_GZIP + if (soap->zlib_out != SOAP_ZLIB_DEFLATE) + { memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10); + soap->d_stream->next_out = (Byte*)soap->z_buf + 10; + soap->d_stream->avail_out = SOAP_BUFLEN - 10; + soap->z_crc = crc32(0L, NULL, 0); + soap->zlib_out = SOAP_ZLIB_GZIP; + if (soap->z_dict) + *((Byte*)soap->z_buf + 2) = 0xff; + if (deflateInit2(soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + } + else +#endif + if (deflateInit(soap->d_stream, soap->z_level) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + if (soap->z_dict) + { if (deflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n")); + soap->zlib_state = SOAP_ZLIB_DEFLATE; + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + ERR_clear_error(); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); + soap->part = SOAP_BEGIN; +#ifndef WITH_LEANER + if (soap->fprepareinitsend && (soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap->fprepareinitsend(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_embedded(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (soap_pointer_lookup(soap, p, t, &pp)) + { pp->mark1 = 1; + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t)); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_reference(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (!p || (soap->mode & SOAP_XML_TREE)) + return 1; + if (soap_pointer_lookup(soap, p, t, &pp)) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp)) + { pp->mark1 = 0; + pp->mark2 = 0; + } + else + return 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t) +{ register int i; + struct soap_plist *pp; + if (!p || !a->__ptr) + return 1; + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (i) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (!soap_pointer_enter(soap, p, a, n, t, &pp)) + return 1; + else + { pp->mark1 = 0; + pp->mark2 = 0; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array reference %p ptr=%p dim=%d type=%d (%d %d)\n", p, a->__ptr, n, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embedded_id(struct soap *soap, int id, const void *p, int t) +{ struct soap_plist *pp = NULL; + if (soap->mode & SOAP_XML_TREE) + return id; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (id < 0) + { id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 2; + else + pp->mark2 = 2; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id multiref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return -1; + } + return id; + } + if (id < 0) + id = soap_pointer_lookup(soap, p, t, &pp); + else if (id && !soap_pointer_lookup(soap, p, t, &pp)) + return 0; + if (id && pp) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id embedded ref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 != 0; + return pp->mark2 != 0; + } + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 1; + return pp->mark2 == 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_single(struct soap *soap, struct soap_plist *pp) +{ if (soap->part == SOAP_IN_HEADER) + return 1; + if (!pp) + return 0; + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 0; + return pp->mark2 == 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return; + if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attachment(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, const char *aid, const char *atype, const char *aoptions, int n, const char *type, int t) +{ +#ifndef WITH_NOIDREF + struct soap_plist *pp; + int i; + if (!p || !a->__ptr || (!aid && !atype)) + return soap_element_id(soap, tag, id, p, a, n, type, t); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:SOAP_STR_EOS, id, atype?atype:SOAP_STR_EOS)); + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (!i) + { i = soap_pointer_enter(soap, p, a, n, t, &pp); + if (!i) + { soap->error = SOAP_EOM; + return -1; + } + } + if (id <= 0) + id = i; + if (!aid) + { sprintf(soap->tmpbuf, soap->dime_id_format, id); + aid = soap_strdup(soap, soap->tmpbuf); + } + /* Add MTOM xop:Include element when necessary */ + /* TODO: this code to be obsoleted with new import/xop.h conventions */ + if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include")) + { if (soap_element_begin_out(soap, tag, 0, type) + || soap_element_href(soap, "xop:Include", 0, "xmlns:xop=\"http://www.w3.org/2004/08/xop/include\" href", aid) + || soap_element_end_out(soap, tag)) + return soap->error; + } + else if (soap_element_href(soap, tag, 0, "href", aid)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (pp->mark1 != 3) + { struct soap_multipart *content; + if (soap->mode & SOAP_ENC_MTOM) + content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size); + else + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size); + if (!content) + { soap->error = SOAP_EOM; + return -1; + } + if (!strncmp(aid, "cid:", 4)) /* RFC 2111 */ + { if (soap->mode & SOAP_ENC_MTOM) + { char *s = (char*)soap_malloc(soap, strlen(aid) - 1); + if (s) + { *s = '<'; + strcpy(s + 1, aid + 4); + strcat(s, ">"); + content->id = s; + } + } + else + content->id = aid + 4; + } + else + content->id = aid; + content->type = atype; + content->options = aoptions; + content->encoding = SOAP_MIME_BINARY; + pp->mark1 = 3; + } + } + else + pp->mark2 = 3; +#endif + return -1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_iht(struct soap *soap) +{ register int i; + for (i = 0; i < SOAP_IDHASH; i++) + soap->iht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_iht(struct soap *soap) +{ register int i; + register struct soap_ilist *ip = NULL, *p = NULL; + register struct soap_flist *fp = NULL, *fq = NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = p) + { for (fp = ip->flist; fp; fp = fq) + { fq = fp->next; + SOAP_FREE(soap, fp); + } + p = ip->next; + SOAP_FREE(soap, ip); + } + soap->iht[i] = NULL; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_lookup(struct soap *soap, const char *id) +{ register struct soap_ilist *ip = NULL; + for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next) + if (!strcmp(ip->id, id)) + return ip; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_enter(struct soap *soap, const char *id) +{ register size_t h; + register struct soap_ilist *ip; + ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id)); + if (ip) + { h = soap_hash(id); + strcpy(ip->id, id); + ip->next = soap->iht[h]; + soap->iht[h] = ip; + } + return ip; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_malloc(struct soap *soap, size_t n) +{ register char *p; + if (!n) + return (void*)SOAP_NON_NULL; + if (!soap) + return SOAP_MALLOC(soap, n); + if (soap->fmalloc) + p = (char*)soap->fmalloc(soap, n); + else + { n += sizeof(short); + n += (-(long)n) & (sizeof(void*)-1); /* align at 4-, 8- or 16-byte boundary */ + if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + /* set the canary to detect corruption */ + *(unsigned short*)(p + n - sizeof(unsigned short)) = (unsigned short)SOAP_CANARY; + /* keep chain of alloced cells for destruction */ + *(void**)(p + n) = soap->alist; + *(size_t*)(p + n + sizeof(void*)) = n; + soap->alist = p + n; + } + soap->alloced = 1; + return p; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +static void +soap_init_mht(struct soap *soap) +{ register int i; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->mht[i] = NULL; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +static void +soap_free_mht(struct soap *soap) +{ register int i; + register struct soap_mlist *mp, *mq; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + { for (mp = soap->mht[i]; mp; mp = mq) + { mq = mp->next; + if (mp->live) + fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr); + free(mp); + } + soap->mht[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_track_malloc(struct soap *soap, const char *file, int line, size_t size) +{ register void *p = malloc(size); + if (soap) + { register size_t h = soap_hash_ptr(p); + register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist)); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p)); + mp->next = soap->mht[h]; + mp->ptr = p; + mp->file = file; + mp->line = line; + mp->live = 1; + soap->mht[h] = mp; + } + return p; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_track_free(struct soap *soap, const char *file, int line, void *p) +{ register size_t h = soap_hash_ptr(p); + register struct soap_mlist *mp; + for (mp = soap->mht[h]; mp; mp = mp->next) + if (mp->ptr == p) + break; + if (mp) + { if (mp->live) + { free(p); + if (soap->fdebug[SOAP_INDEX_TEST]) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p)); + } + mp->live = 0; + } + else + fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line); + } + else + fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +static void +soap_track_unlink(struct soap *soap, const void *p) +{ register size_t h = soap_hash_ptr(p); + register struct soap_mlist *mp; + for (mp = soap->mht[h]; mp; mp = mp->next) + if (mp->ptr == p) + break; + if (mp) + mp->live = 0; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_dealloc(struct soap *soap, void *p) +{ if (soap_check_state(soap)) + return; + if (p) + { register char **q; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { + if (*(unsigned short*)(char*)(*q - sizeof(unsigned short)) != (unsigned short)SOAP_CANARY) + { +#ifdef SOAP_MEM_DEBUG + fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n"); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n")); + DBGHEX(TEST, *q - 200, 200); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n")); + soap->error = SOAP_MOE; + return; + } + if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p)); + SOAP_FREE(soap, p); + return; + } + } + soap_delete(soap, p); + } + else + { register char *q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n")); + while (soap->alist) + { q = (char*)soap->alist; + if (*(unsigned short*)(char*)(q - sizeof(unsigned short)) != (unsigned short)SOAP_CANARY) + { +#ifdef SOAP_MEM_DEBUG + fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n"); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n")); + DBGHEX(TEST, q - 200, 200); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n")); + soap->error = SOAP_MOE; + return; + } + soap->alist = *(void**)q; + q -= *(size_t*)(q + sizeof(void*)); + SOAP_FREE(soap, q); + } + /* we must assume these were deallocated: */ + soap->action = NULL; + soap->fault = NULL; + soap->header = NULL; + soap->userid = NULL; + soap->passwd = NULL; + soap->authrealm = NULL; + soap->http_content = NULL; +#ifndef WITH_LEANER + soap_clr_mime(soap); +#endif + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_delete(struct soap *soap, void *p) +{ register struct soap_clist **cp; + if (soap_check_state(soap)) + return; + cp = &soap->clist; + if (p) + { while (*cp) + { if (p == (*cp)->ptr) + { register struct soap_clist *q = *cp; + *cp = q->next; + if (q->fdelete(q)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type)); +#ifdef SOAP_MEM_DEBUG + fprintf(stderr, "new(object type = %d) = %p not freed: deletion callback failed\n", q->type, q->ptr); +#endif + } + SOAP_FREE(soap, q); + return; + } + cp = &(*cp)->next; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p)); + } + else + { while (*cp) + { register struct soap_clist *q = *cp; + *cp = q->next; + if (q->fdelete(q)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type)); +#ifdef SOAP_MEM_DEBUG + fprintf(stderr, "new(object type = %d) = %p not freed: deletion callback failed\n", q->type, q->ptr); +#endif + } + SOAP_FREE(soap, q); + } + } + soap->fault = NULL; /* this was possibly deallocated */ + soap->header = NULL; /* this was possibly deallocated */ +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_delegate_deletion(struct soap *soap, struct soap *soap_to) +{ register struct soap_clist *cp; + register char **q; +#ifdef SOAP_MEM_DEBUG + register void *p; + register struct soap_mlist **mp, *mq; + size_t h; +#endif + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { + if (*(unsigned short*)(char*)(*q - sizeof(unsigned short)) != (unsigned short)SOAP_CANARY) + { +#ifdef SOAP_MEM_DEBUG + fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n"); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n")); + DBGHEX(TEST, *q - 200, 200); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n")); + soap->error = SOAP_MOE; + return; + } +#ifdef SOAP_MEM_DEBUG + p = (void*)(*q - *(size_t*)(*q + sizeof(void*))); + h = soap_hash_ptr(p); + for (mp = &soap->mht[h]; *mp; mp = &(*mp)->next) + { if ((*mp)->ptr == p) + { mq = *mp; + *mp = mq->next; + mq->next = soap_to->mht[h]; + soap_to->mht[h] = mq; + break; + } + } +#endif + } + *q = (char*)soap_to->alist; + soap_to->alist = soap->alist; + soap->alist = NULL; + cp = soap_to->clist; + if (cp) + { while (cp->next) + cp = cp->next; + cp->next = soap->clist; + } + else + soap_to->clist = soap->clist; + soap->clist = NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_clist * +SOAP_FMAC2 +soap_link(struct soap *soap, void *p, int t, int n, int (*fdelete)(struct soap_clist*)) +{ register struct soap_clist *cp; + if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist)))) + { cp->next = soap->clist; + cp->type = t; + cp->size = n; + cp->ptr = p; + cp->fdelete = fdelete; + soap->clist = cp; + } + return cp; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_unlink(struct soap *soap, const void *p) +{ register char **q; + register struct soap_clist **cp; + if (!soap || !p) + return; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p)); +#ifdef SOAP_MEM_DEBUG + soap_track_unlink(soap, p); +#endif + return; + } + } + for (cp = &soap->clist; *cp; cp = &(*cp)->next) + { if (p == (*cp)->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p)); + q = (char**)*cp; + *cp = (*cp)->next; + SOAP_FREE(soap, q); + return; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_lookup_type(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + if (id && *id) + { ip = soap_lookup(soap, id); + if (ip) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type)); + return ip->type; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k) +{ struct soap_ilist *ip; + void **q; + if (!p || !id || !*id) + return p; + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + if (!ip) + { if (!(ip = soap_enter(soap, id))) /* new hash table entry for string id */ + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n)); + ip->type = t; + ip->size = n; + ip->link = p; + ip->copy = NULL; + ip->flist = NULL; + ip->ptr = NULL; + ip->level = k; + *p = NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n)); + if (ip->type != t) + { strcpy(soap->id, id); + soap->error = SOAP_HREF; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: href='%s' id-type=%d href-type=%d\n", id, ip->type, t)); + return NULL; + } + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return NULL; + *p = (void*)q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + *p = ip->ptr; + } + else if (ip->level > k) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id)); + while (ip->level > k) + { void *s, **r = &ip->link; + q = (void**)ip->link; + while (q) + { *r = (void*)soap_malloc(soap, sizeof(void*)); + if (!*r) + return NULL; + s = *q; + *q = *r; + r = (void**)*r; + q = (void**)s; + } + *r = NULL; + ip->size = n; + ip->copy = NULL; + ip->level = ip->level - 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n)); + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return NULL; + *p = q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t)) +{ struct soap_ilist *ip; + if (!p || !href || !*href) + return p; + ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */ + if (!ip) + { if (!(ip = soap_enter(soap, href))) /* new hash table entry for string id */ + return NULL; + ip->type = st; + ip->size = n; + ip->link = NULL; + ip->copy = NULL; + ip->ptr = NULL; + ip->level = 0; + ip->flist = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry href='%s' type=%d size=%lu level=%d location=%p\n", href, st, (unsigned long)n, k, p)); + } + else if (ip->type != st || (ip->level == k && ip->size != n)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", href, ip->type, (unsigned long)ip->size, k, st, (unsigned long)n)); + strcpy(soap->id, href); + soap->error = SOAP_HREF; + return NULL; + } + if (fcopy || n < sizeof(void*) || *href != '#') + { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist)); + if (!fp) + { soap->error = SOAP_EOM; + return NULL; + } + fp->next = ip->flist; + fp->type = tt; + fp->ptr = p; + fp->level = k; + fp->len = len; + if (fcopy) + fp->fcopy = fcopy; + else + fp->fcopy = soap_fcopy; + ip->flist = fp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u len=%lu href='%s'\n", st, tt, (unsigned long)n, p, k, (unsigned long)len, href)); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href)); + *(void**)p = ip->copy; + ip->copy = p; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)) +{ +#ifndef WITH_NOIDREF + struct soap_ilist *ip; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + soap->alloced = 0; + if (!p) + { if (finstantiate) + p = finstantiate(soap, t, type, arrayType, &n); + else + p = soap_malloc(soap, n); + if (p) + soap->alloced = 1; + } +#ifndef WITH_NOIDREF + if (!id || !*id) +#endif + return p; +#ifndef WITH_NOIDREF + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p)); + if (!ip) + { if (!(ip = soap_enter(soap, id))) /* new hash table entry for string id */ + return NULL; + ip->type = t; + ip->link = NULL; + ip->copy = NULL; + ip->flist = NULL; + ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry id='%s' type=%d size=%lu level=%u location=%p\n", id, t, (unsigned long)n, k, p)); + } + else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", id, ip->type, (unsigned long)ip->size, k, t, (unsigned long)n)); + strcpy(soap->id, id); + soap->error = SOAP_HREF; + return NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id)); + strcpy(soap->id, id); + soap->error = SOAP_DUPLICATE_ID; + return NULL; + } + else + { ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update entry id='%s' type=%d location=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + } + return ip->ptr; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n)); + memcpy(p, q, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_send(struct soap *soap) +{ +#ifndef WITH_LEANER + int err; + if (soap->dime.list) + { /* SOAP body referenced attachments must appear first */ + soap->dime.last->next = soap->dime.first; + soap->dime.first = soap->dime.list->next; + soap->dime.list->next = NULL; + soap->dime.last = soap->dime.list; + } + if (!(err = soap_putdime(soap))) + err = soap_putmime(soap); + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + if (err) + return err; +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n")); + if (soap->mode & SOAP_IO) /* need to flush the remaining data in buffer */ + { if (soap_flush(soap)) +#ifdef WITH_ZLIB + { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(soap->d_stream); + } + return soap->error; + } +#else + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { int r; + soap->d_stream->avail_in = 0; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n")); + r = deflate(soap->d_stream, Z_FINISH); + if (soap->d_stream->avail_out != SOAP_BUFLEN) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream->avail_out)) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(soap->d_stream); + return soap->error; + } + soap->d_stream->next_out = (Byte*)soap->z_buf; + soap->d_stream->avail_out = SOAP_BUFLEN; + } + } while (r == Z_OK); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated total %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out)); + soap->z_ratio_out = (float)soap->d_stream->total_out / (float)soap->d_stream->total_in; + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_state = SOAP_ZLIB_NONE; + if (deflateEnd(soap->d_stream) != Z_OK || r != Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS)); + return soap->error = SOAP_ZLIB_ERROR; + } +#ifdef WITH_GZIP + if (soap->zlib_out != SOAP_ZLIB_DEFLATE) + { soap->z_buf[0] = soap->z_crc & 0xFF; + soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF; + soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF; + soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF; + soap->z_buf[4] = soap->d_stream->total_in & 0xFF; + soap->z_buf[5] = (soap->d_stream->total_in >> 8) & 0xFF; + soap->z_buf[6] = (soap->d_stream->total_in >> 16) & 0xFF; + soap->z_buf[7] = (soap->d_stream->total_in >> 24) & 0xFF; + if (soap_flush_raw(soap, soap->z_buf, 8)) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc)); + } +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { char *p; +#ifndef WITH_NOHTTP + if (!(soap->mode & SOAP_ENC_XML)) + { soap->mode--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size)); + if (soap->status >= SOAP_POST) + soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size); + else if (soap->status != SOAP_STOP) + soap->error = soap->fresponse(soap, soap->status, soap->blist->size); + if (soap->error || soap_flush(soap)) + return soap->error; + soap->mode++; + } +#endif + for (p = soap_first_block(soap, NULL); p; p = soap_next_block(soap, NULL)) + { DBGMSG(SENT, p, soap_block_size(soap, NULL)); + if ((soap->error = soap->fsend(soap, p, soap_block_size(soap, NULL)))) + { soap_end_block(soap, NULL); + return soap->error; + } + } + soap_end_block(soap, NULL); + } +#ifndef WITH_LEANER + else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { DBGMSG(SENT, "\r\n0\r\n\r\n", 7); + if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7))) + return soap->error; + } +#endif + } +#ifdef WITH_TCPFIN +#ifdef WITH_OPENSSL + if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP)) + soap->fshutdownsocket(soap, soap->socket, SOAP_SHUT_WR); /* Send TCP FIN */ +#else + if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP)) + soap->fshutdownsocket(soap, soap->socket, SOAP_SHUT_WR); /* Send TCP FIN */ +#endif +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n")); + soap->omode &= ~SOAP_XML_SEC; + soap->count = 0; + soap->part = SOAP_END; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_recv(struct soap *soap) +{ soap->part = SOAP_END; +#ifndef WITH_LEAN + soap->wsuid = NULL; /* reset before next send */ + soap->c14nexclude = NULL; /* reset before next send */ +#endif +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap)) + { soap->dime.first = NULL; + soap->dime.last = NULL; + return soap->error; + } + soap->dime.list = soap->dime.first; + soap->dime.first = NULL; + soap->dime.last = NULL; + /* Check if MIME attachments and mime-post-check flag is set, if so call soap_resolve() and return */ + if (soap->mode & SOAP_ENC_MIME) + { + if (soap->mode & SOAP_MIME_POSTCHECK) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Post checking MIME attachments\n")); + if (!soap->keep_alive) + soap->keep_alive = -1; +#ifndef WITH_NOIDREF + soap_resolve(soap); +#endif + return SOAP_OK; + } + if (soap_getmime(soap)) + return soap->error; + } + soap->mime.list = soap->mime.first; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + if (soap->xlist) + { struct soap_multipart *content; + for (content = soap->mime.list; content; content = content->next) + soap_resolve_attachment(soap, content); + } +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n")); +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { /* Make sure end of compressed content is reached */ + while (soap->d_stream->next_out != Z_NULL) + if ((int)soap_get1(soap) == EOF) + break; + soap->mode &= ~SOAP_ENC_ZLIB; + memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->bufidx = (char*)soap->d_stream->next_in - soap->z_buf; + soap->buflen = soap->z_buflen; + soap->zlib_state = SOAP_ZLIB_NONE; + if (inflateEnd(soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Inflate end ok\n")); +#ifdef WITH_GZIP + if (soap->zlib_in == SOAP_ZLIB_GZIP) + { soap_wchar c; + short i; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Inflate gzip crc check\n")); + for (i = 0; i < 8; i++) + { if ((int)(c = soap_get1(soap)) == EOF) + return soap->error = SOAP_EOF; + soap->z_buf[i] = (char)c; + } + if (soap->z_crc != ((uLong)(unsigned char)soap->z_buf[0] | ((uLong)(unsigned char)soap->z_buf[1] << 8) | ((uLong)(unsigned char)soap->z_buf[2] << 16) | ((uLong)(unsigned char)soap->z_buf[3] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc)); + return soap->error = SOAP_ZLIB_ERROR; + } + if (soap->d_stream->total_out != ((uLong)(unsigned char)soap->z_buf[4] | ((uLong)(unsigned char)soap->z_buf[5] << 8) | ((uLong)(unsigned char)soap->z_buf[6] << 16) | ((uLong)(unsigned char)soap->z_buf[7] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n")); + return soap->error = SOAP_ZLIB_ERROR; + } + } + soap->zlib_in = SOAP_ZLIB_NONE; +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + while ((int)soap_getchar(soap) != EOF) /* advance to last chunk */ + ; +#ifndef WITH_NOIDREF + if (soap_resolve(soap)) + return soap->error; +#endif +#ifndef WITH_LEANER + if (soap->xlist) + { if (soap->mode & SOAP_ENC_MTOM) + return soap->error = SOAP_MIME_HREF; + return soap->error = SOAP_DIME_HREF; + } +#endif + soap_free_ns(soap); +#ifndef WITH_LEANER + if (soap->fpreparefinalrecv) + return soap->error = soap->fpreparefinalrecv(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_temp(struct soap *soap) +{ register struct soap_attribute *tp, *tq; + register struct Namespace *ns; + soap_free_ns(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n")); + while (soap->blist) + soap_end_block(soap, NULL); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n")); + for (tp = soap->attributes; tp; tp = tq) + { tq = tp->next; + if (tp->value) + SOAP_FREE(soap, tp->value); + SOAP_FREE(soap, tp); + } + soap->attributes = NULL; +#ifdef WITH_FAST + if (soap->labbuf) + SOAP_FREE(soap, soap->labbuf); + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; +#endif + ns = soap->local_namespaces; + if (ns) + { for (; ns->id; ns++) + { if (ns->out) + { if (soap->encodingStyle == ns->out) + soap->encodingStyle = SOAP_STR_EOS; + SOAP_FREE(soap, ns->out); + ns->out = NULL; + } + if (soap->encodingStyle == ns->ns) + soap->encodingStyle = SOAP_STR_EOS; + } + SOAP_FREE(soap, soap->local_namespaces); + soap->local_namespaces = NULL; + } +#ifndef WITH_LEANER + while (soap->xlist) + { struct soap_xlist *xp = soap->xlist->next; + SOAP_FREE(soap, soap->xlist); + soap->xlist = xp; + } +#endif +#ifndef WITH_NOIDREF + soap_free_pht(soap); + soap_free_iht(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static void +soap_free_ns(struct soap *soap) +{ register struct soap_nlist *np, *nq; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n")); + for (np = soap->nlist; np; np = nq) + { nq = np->next; + SOAP_FREE(soap, np); + } + soap->nlist = NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) +static void +soap_init_logs(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + { soap->logfile[i] = NULL; + soap->fdebug[i] = NULL; + } +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_open_logfile(struct soap *soap, int i) +{ if (soap->logfile[i]) + soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a"); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_close_logfile(struct soap *soap, int i) +{ if (soap->fdebug[i]) + { fclose(soap->fdebug[i]); + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_close_logfiles(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + soap_close_logfile(soap, i); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_set_logfile(struct soap *soap, int i, const char *logfile) +{ const char *s; + char *t = NULL; + soap_close_logfile(soap, i); + s = soap->logfile[i]; + soap->logfile[i] = logfile; + if (s) + SOAP_FREE(soap, (void*)s); + if (logfile) + if ((t = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1))) + strcpy(t, logfile); + soap->logfile[i] = t; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_recv_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_RECV, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_sent_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_SENT, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_test_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_TEST, logfile); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy(const struct soap *soap) +{ return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy_context(struct soap *copy, const struct soap *soap) +{ if (soap_check_state(soap)) + return NULL; + if (copy) + { register struct soap_plugin *p = NULL; +#ifdef __cplusplus + *copy = *soap; +#else + memcpy(copy, soap, sizeof(struct soap)); +#endif + copy->state = SOAP_COPY; + copy->error = SOAP_OK; + copy->userid = NULL; + copy->passwd = NULL; + copy->nlist = NULL; + copy->blist = NULL; + copy->clist = NULL; + copy->alist = NULL; + copy->attributes = NULL; + copy->labbuf = NULL; + copy->lablen = 0; + copy->labidx = 0; +#ifdef SOAP_MEM_DEBUG + soap_init_mht(copy); +#endif +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) + soap_init_logs(copy); +#endif +#ifdef SOAP_DEBUG + soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]); + soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]); + soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]); +#endif +#ifdef WITH_C_LOCALE + copy->c_locale = duplocale(soap->c_locale); +#else + copy->c_locale = NULL; +#endif +#ifdef WITH_OPENSSL + copy->bio = NULL; + copy->ssl = NULL; + copy->session = NULL; +#endif +#ifdef WITH_GNUTLS + copy->session = NULL; +#endif +#ifdef WITH_ZLIB + copy->d_stream = (z_stream*)SOAP_MALLOC(copy, sizeof(z_stream)); + copy->d_stream->zalloc = Z_NULL; + copy->d_stream->zfree = Z_NULL; + copy->d_stream->opaque = Z_NULL; + copy->z_buf = NULL; +#endif + copy->local_namespaces = NULL; +#ifndef WITH_NOIDREF + soap_init_iht(copy); + soap_init_pht(copy); +#endif + copy->header = NULL; + copy->fault = NULL; + copy->action = NULL; +#ifndef WITH_LEAN +#ifdef WITH_COOKIES + copy->cookies = soap_copy_cookies(copy, soap); +#else + copy->cookies = NULL; +#endif +#endif + copy->plugins = NULL; + for (p = soap->plugins; p; p = p->next) + { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin)); + if (!q) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id)); + *q = *p; + if (p->fcopy && p->fcopy(copy, q, p)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not copy plugin '%s'\n", p->id)); + SOAP_FREE(copy, q); + return NULL; + } + q->next = copy->plugins; + copy->plugins = q; + } + } + return copy; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_copy_stream(struct soap *copy, struct soap *soap) +{ copy->mode = soap->mode; + copy->imode = soap->imode; + copy->omode = soap->omode; + copy->socket = soap->socket; + copy->recv_timeout = soap->recv_timeout; + copy->send_timeout = soap->send_timeout; +#if defined(__cplusplus) && !defined(WITH_LEAN) + copy->os = soap->os; + copy->is = soap->is; +#endif + copy->sendfd = soap->sendfd; + copy->recvfd = soap->recvfd; + copy->bufidx = soap->bufidx; + copy->buflen = soap->buflen; + copy->ahead = soap->ahead; + copy->cdata = soap->cdata; + copy->chunksize = soap->chunksize; + copy->chunkbuflen = soap->chunkbuflen; + copy->keep_alive = soap->keep_alive; + copy->tcp_keep_alive = soap->tcp_keep_alive; + copy->tcp_keep_idle = soap->tcp_keep_idle; + copy->tcp_keep_intvl = soap->tcp_keep_intvl; + copy->tcp_keep_cnt = soap->tcp_keep_cnt; + copy->max_keep_alive = soap->max_keep_alive; +#ifndef WITH_NOIO + copy->peer = soap->peer; + copy->peerlen = soap->peerlen; +#endif +#ifdef WITH_OPENSSL + copy->bio = soap->bio; + copy->ssl = soap->ssl; + copy->ctx = soap->ctx; +#endif +#ifdef WITH_GNUTLS + copy->session = soap->session; /* TODO: GNUTLS provides a dup? */ +#endif +#ifdef WITH_ZLIB + copy->zlib_state = soap->zlib_state; + copy->zlib_in = soap->zlib_in; + copy->zlib_out = soap->zlib_out; + copy->d_stream = (z_stream*)SOAP_MALLOC(copy, sizeof(z_stream)); + memcpy(copy->d_stream, soap->d_stream, sizeof(z_stream)); + copy->z_crc = soap->z_crc; + copy->z_ratio_in = soap->z_ratio_in; + copy->z_ratio_out = soap->z_ratio_out; + copy->z_buf = NULL; + copy->z_buflen = soap->z_buflen; + copy->z_level = soap->z_level; + if (soap->z_buf && soap->zlib_state != SOAP_ZLIB_NONE) + { copy->z_buf = (char*)SOAP_MALLOC(copy, SOAP_BUFLEN); + memcpy(copy->z_buf, soap->z_buf, sizeof(soap->z_buf)); + } + copy->z_dict = soap->z_dict; + copy->z_dict_len = soap->z_dict_len; +#endif + memcpy(copy->buf, soap->buf, sizeof(soap->buf)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_stream(struct soap *soap) +{ soap->socket = SOAP_INVALID_SOCKET; +#ifdef WITH_OPENSSL + soap->bio = NULL; + soap->ssl = NULL; +#endif +#ifdef WITH_GNUTLS + soap->xcred = NULL; + soap->acred = NULL; + soap->cache = NULL; + soap->session = NULL; /* TODO: GNUTLS free (when dupped)? */ + soap->dh_params = NULL; + soap->rsa_params = NULL; +#endif +#ifdef WITH_ZLIB + if (soap->d_stream) + SOAP_FREE(soap, soap->d_stream); + soap->d_stream = NULL; + if (soap->z_buf) + SOAP_FREE(soap, soap->z_buf); + soap->z_buf = NULL; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init(struct soap *soap) +{ soap->state = SOAP_INIT; +#ifdef SOAP_MEM_DEBUG + soap_init_mht(soap); +#endif +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) + soap_init_logs(soap); +#endif +#ifdef SOAP_DEBUG + soap_set_test_logfile(soap, "TEST.log"); + soap_set_sent_logfile(soap, "SENT.log"); + soap_set_recv_logfile(soap, "RECV.log"); +#endif + soap->version = 0; + soap_imode(soap, SOAP_IO_DEFAULT); + soap_omode(soap, SOAP_IO_DEFAULT); + soap->plugins = NULL; + soap->user = NULL; + soap->userid = NULL; + soap->passwd = NULL; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fput = http_put; + soap->fget = http_get; + soap->fdel = http_405; + soap->fopt = http_405; + soap->fhead = http_405; + soap->fform = NULL; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif + soap->fheader = NULL; + soap->fconnect = NULL; + soap->fdisconnect = NULL; +#ifndef WITH_NOIO + soap->ipv6_multicast_if = 0; + soap->ipv4_multicast_if = NULL; +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif + soap->fseterror = NULL; + soap->fignore = NULL; + soap->fserveloop = NULL; + soap->fplugin = fplugin; + soap->fmalloc = NULL; +#ifndef WITH_LEANER + soap->fprepareinitsend = NULL; + soap->fprepareinitrecv = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; + soap->fpreparefinalsend = NULL; + soap->fpreparefinalrecv = NULL; + soap->fdimereadopen = NULL; + soap->fdimewriteopen = NULL; + soap->fdimereadclose = NULL; + soap->fdimewriteclose = NULL; + soap->fdimeread = NULL; + soap->fdimewrite = NULL; + soap->fmimereadopen = NULL; + soap->fmimewriteopen = NULL; + soap->fmimereadclose = NULL; + soap->fmimewriteclose = NULL; + soap->fmimeread = NULL; + soap->fmimewrite = NULL; +#endif + soap->float_format = "%.9G"; /* Alternative: use "%G" */ + soap->double_format = "%.17lG"; /* Alternative: use "%lG" */ + soap->dime_id_format = "cid:id%d"; /* default DIME id format */ + soap->http_version = "1.1"; + soap->proxy_http_version = "1.0"; + soap->http_content = NULL; + soap->actor = NULL; + soap->lang = "en"; + soap->keep_alive = 0; + soap->tcp_keep_alive = 0; + soap->tcp_keep_idle = 0; + soap->tcp_keep_intvl = 0; + soap->tcp_keep_cnt = 0; + soap->max_keep_alive = SOAP_MAXKEEPALIVE; + soap->recv_timeout = 0; + soap->send_timeout = 0; + soap->connect_timeout = 0; + soap->accept_timeout = 0; + soap->socket_flags = 0; + soap->connect_flags = 0; + soap->bind_flags = 0; + soap->accept_flags = 0; + soap->linger_time = 0; + soap->ip = 0; + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; + soap->encodingStyle = SOAP_STR_EOS; +#ifndef WITH_NONAMESPACES + soap->namespaces = namespaces; +#else + soap->namespaces = NULL; +#endif + soap->local_namespaces = NULL; + soap->nlist = NULL; + soap->blist = NULL; + soap->clist = NULL; + soap->alist = NULL; + soap->attributes = NULL; + soap->header = NULL; + soap->fault = NULL; + soap->master = SOAP_INVALID_SOCKET; + soap->socket = SOAP_INVALID_SOCKET; + soap->os = NULL; + soap->is = NULL; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; + soap->xlist = NULL; +#endif +#ifndef UNDER_CE + soap->recvfd = 0; + soap->sendfd = 1; +#else + soap->recvfd = stdin; + soap->sendfd = stdout; +#endif + soap->host[0] = '\0'; + soap->port = 0; + soap->action = NULL; + soap->proxy_host = NULL; + soap->proxy_port = 8080; + soap->proxy_userid = NULL; + soap->proxy_passwd = NULL; + soap->authrealm = NULL; + soap->prolog = NULL; +#ifdef WITH_ZLIB + soap->zlib_state = SOAP_ZLIB_NONE; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream = (z_stream*)SOAP_MALLOC(soap, sizeof(z_stream)); + soap->d_stream->zalloc = Z_NULL; + soap->d_stream->zfree = Z_NULL; + soap->d_stream->opaque = Z_NULL; + soap->z_buf = NULL; + soap->z_level = 6; + soap->z_dict = NULL; + soap->z_dict_len = 0; +#endif +#ifndef WITH_LEAN + soap->wsuid = NULL; + soap->c14nexclude = NULL; + soap->cookies = NULL; + soap->cookie_domain = NULL; + soap->cookie_path = NULL; + soap->cookie_max = 32; +#endif +#ifdef WMW_RPM_IO + soap->rpmreqid = NULL; +#endif +#ifdef PALM + palmNetLibOpen(); +#endif +#ifndef WITH_NOIDREF + soap_init_iht(soap); + soap_init_pht(soap); +#endif +#ifdef WITH_OPENSSL + if (!soap_ssl_init_done) + soap_ssl_init(); + soap->fsslauth = ssl_auth_init; + soap->fsslverify = ssl_verify_callback; + soap->bio = NULL; + soap->ssl = NULL; + soap->ctx = NULL; + soap->session = NULL; + soap->ssl_flags = SOAP_SSL_DEFAULT; + soap->keyfile = NULL; + soap->password = NULL; + soap->cafile = NULL; + soap->capath = NULL; + soap->crlfile = NULL; + soap->dhfile = NULL; + soap->randfile = NULL; +#endif +#ifdef WITH_GNUTLS + if (!soap_ssl_init_done) + soap_ssl_init(); + soap->fsslauth = ssl_auth_init; + soap->fsslverify = NULL; + soap->xcred = NULL; + soap->acred = NULL; + soap->cache = NULL; + soap->session = NULL; + soap->ssl_flags = SOAP_SSL_DEFAULT; + soap->keyfile = NULL; + soap->password = NULL; + soap->cafile = NULL; + soap->capath = NULL; + soap->crlfile = NULL; + soap->dh_params = NULL; + soap->rsa_params = NULL; +#endif +#ifdef WITH_C_LOCALE + soap->c_locale = newlocale(LC_ALL_MASK, "C", NULL); +#else + soap->c_locale = NULL; +#endif + soap->buflen = 0; + soap->bufidx = 0; +#ifndef WITH_LEANER + soap->dime.chunksize = 0; + soap->dime.buflen = 0; +#endif + soap->null = 0; + soap->position = 0; + soap->encoding = 0; + soap->mustUnderstand = 0; + soap->ns = 0; + soap->part = SOAP_END; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + soap->peeked = 0; + soap->ahead = 0; + soap->idnum = 0; + soap->level = 0; + soap->endpoint[0] = '\0'; + soap->error = SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init1(struct soap *soap, soap_mode mode) +{ soap_init2(soap, mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init2(struct soap *soap, soap_mode imode, soap_mode omode) +{ soap_init(soap); + soap_imode(soap, imode); + soap_omode(soap, omode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_begin(struct soap *soap) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reinitializing context\n")); + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + soap->null = 0; + soap->position = 0; + soap->encoding = 0; + soap->mustUnderstand = 0; + soap->mode = 0; + soap->ns = 0; + soap->part = SOAP_END; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + soap->error = SOAP_OK; + soap->peeked = 0; + soap->ahead = 0; + soap->idnum = 0; + soap->level = 0; + soap->endpoint[0] = '\0'; +#ifndef WITH_LEANER + soap->dime.chunksize = 0; + soap->dime.buflen = 0; +#endif + soap_free_temp(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end(struct soap *soap) +{ if (soap_check_state(soap)) + return; + soap_free_temp(soap); + soap_dealloc(soap, NULL); + while (soap->clist) + { register struct soap_clist *cp = soap->clist->next; + SOAP_FREE(soap, soap->clist); + soap->clist = cp; + } + soap_closesock(soap); +#ifdef SOAP_DEBUG + soap_close_logfiles(soap); +#endif +#ifdef PALM + palmNetLibClose(); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_namespaces(struct soap *soap, const struct Namespace *p) +{ register struct Namespace *ns = soap->local_namespaces; + register struct soap_nlist *np, *nq, *nr; + register unsigned int level = soap->level; + soap->namespaces = p; + soap->local_namespaces = NULL; + soap_set_local_namespaces(soap); + /* reverse the namespace list */ + np = soap->nlist; + soap->nlist = NULL; + if (np) + { nq = np->next; + np->next = NULL; + while (nq) + { nr = nq->next; + nq->next = np; + np = nq; + nq = nr; + } + } + /* then push on new stack */ + while (np) + { register const char *s; + soap->level = np->level; /* preserve element nesting level */ + s = np->ns; + if (!s && np->index >= 0 && ns) + { s = ns[np->index].out; + if (!s) + s = ns[np->index].ns; + } + if (s && soap_push_namespace(soap, np->id, s) == NULL) + return soap->error; + nq = np; + np = np->next; + SOAP_FREE(soap, nq); + } + if (ns) + { register int i; + for (i = 0; ns[i].id; i++) + { if (ns[i].out) + { SOAP_FREE(soap, ns[i].out); + ns[i].out = NULL; + } + } + SOAP_FREE(soap, ns); + } + soap->level = level; /* restore level */ + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_local_namespaces(struct soap *soap) +{ if (soap->namespaces && !soap->local_namespaces) + { register const struct Namespace *ns1; + register struct Namespace *ns2; + register size_t n = 1; + for (ns1 = soap->namespaces; ns1->id; ns1++) + n++; + n *= sizeof(struct Namespace); + ns2 = (struct Namespace*)SOAP_MALLOC(soap, n); + if (ns2) + { memcpy(ns2, soap->namespaces, n); + if (ns2[0].ns) + { if (!strcmp(ns2[0].ns, soap_env1)) + soap->version = 1; + else + soap->version = 2; + } + soap->local_namespaces = ns2; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef PALM_1 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_tagsearch(const char *big, const char *little) +{ if (little) + { register size_t n = strlen(little); + register const char *s = big; + while (s) + { register const char *t = s; + register size_t i; + for (i = 0; i < n; i++, t++) + { if (*t != little[i]) + break; + } + if (*t == '\0' || *t == ' ') + { if (i == n || (i && little[i-1] == ':')) + return s; + } + s = strchr(t, ' '); + if (s) + s++; + } + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_nlist * +SOAP_FMAC2 +soap_lookup_ns(struct soap *soap, const char *tag, size_t n) +{ register struct soap_nlist *np; + for (np = soap->nlist; np; np = np->next) + { if (!strncmp(np->id, tag, n) && !np->id[n]) + return np; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static struct soap_nlist * +soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized) +{ register struct soap_nlist *np; + size_t n, k; + if (soap_tagsearch(soap->c14nexclude, id)) + return NULL; + if (!utilized) + { for (np = soap->nlist; np; np = np->next) + { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns))) + break; + } + if (np) + { if ((np->level < soap->level || !np->ns) && np->index == 1) + utilized = 1; + else + return NULL; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Adding namespace binding (level=%u) '%s' '%s' utilized=%d\n", soap->level, id, ns?ns:"(null)", utilized)); + n = strlen(id); + if (ns) + k = strlen(ns); + else + k = 0; + np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1); + if (!np) + { soap->error = SOAP_EOM; + return NULL; + } + np->next = soap->nlist; + soap->nlist = np; + strcpy(np->id, id); + if (ns) + np->ns = strcpy(np->id + n + 1, ns); + else + np->ns = NULL; + np->level = soap->level; + np->index = utilized; + return np; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static void +soap_utilize_ns(struct soap *soap, const char *tag, size_t n) +{ register struct soap_nlist *np = soap_lookup_ns(soap, tag, n); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Utilizing namespace of '%s'\n", tag)); + if (np) + { if (np->index == 0) + soap_push_ns(soap, np->id, np->ns, 1); + } + else if (strncmp(tag, "xml", 3)) + { strncpy(soap->tmpbuf, tag, n); + soap->tmpbuf[n] = '\0'; + soap_push_ns(soap, soap->tmpbuf, NULL, 1); + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element(struct soap *soap, const char *tag, int id, const char *type) +{ +#ifndef WITH_LEAN + register const char *s; +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:SOAP_STR_EOS)); +#ifdef WITH_DOM +#ifndef WITH_LEAN + if (soap->wsuid && soap_tagsearch(soap->wsuid, tag)) + { size_t i; + for (s = tag, i = 0; *s && i < sizeof(soap->tag); s++, i++) + soap->tag[i] = *s == ':' ? '-' : *s; + soap->tag[sizeof(soap->tag) - 1] = '\0'; + if (soap_set_attr(soap, "wsu:Id", soap->tag, 1)) + return soap->error; + } +#endif + if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL) && !(soap->mode & SOAP_DOM_ASIS)) + { register struct soap_nlist *np; + /* wsu:Id found: clear xmlns renderings, so re-emit them for exc-c14n */ + for (np = soap->nlist; np; np = np->next) + { if (np->index == 2) + np->index = 0; + } + } + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + if (!elt) + return soap->error; + elt->soap = soap; + elt->next = NULL; + elt->prnt = soap->dom; + elt->name = soap_strdup(soap, tag); + elt->elts = NULL; + elt->atts = NULL; + elt->nstr = NULL; + elt->data = NULL; + elt->wide = NULL; + elt->node = NULL; + elt->type = 0; + elt->head = NULL; + elt->tail = NULL; + if (soap->dom) + { struct soap_dom_element *p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = elt; + } + else + soap->dom->elts = elt; + } + soap->dom = elt; + } + else + { +#endif + soap->level++; +#ifndef WITH_LEAN + if (!soap->ns) + { if (!(soap->mode & SOAP_XML_CANONICAL) + && soap_send(soap, soap->prolog ? soap->prolog : "\n")) + return soap->error; + } + else if (soap->mode & SOAP_XML_INDENT) + { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1)) + return soap->error; + soap->body = 1; + } + if ((soap->mode & SOAP_XML_DEFAULTNS) && (s = strchr(tag, ':'))) + { struct Namespace *ns = soap->local_namespaces; + size_t n = s - tag; + if (soap_send_raw(soap, "<", 1) + || soap_send(soap, s + 1)) + return soap->error; + if (soap->nlist && !strncmp(soap->nlist->id, tag, n) && !soap->nlist->id[n]) + ns = NULL; + for (; ns && ns->id; ns++) + { if (*ns->id && (ns->out || ns->ns) && !strncmp(ns->id, tag, n) && !ns->id[n]) + { soap_push_ns(soap, ns->id, ns->out ? ns->out : ns->ns, 0); + if (soap_attribute(soap, "xmlns", ns->out ? ns->out : ns->ns)) + return soap->error; + break; + } + } + } + else +#endif + if (soap_send_raw(soap, "<", 1) + || soap_send(soap, tag)) + return soap->error; +#ifdef WITH_DOM + } +#endif + if (!soap->ns) + { struct Namespace *ns; + int k = -1; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_DEFAULTNS)) + k = 4; /* only produce the first four required entries */ +#endif + for (ns = soap->local_namespaces; ns && ns->id && k; ns++, k--) + { if (*ns->id && (ns->out || ns->ns)) + { sprintf(soap->tmpbuf, "xmlns:%s", ns->id); + if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns)) + return soap->error; + } + } + } + soap->ns = 1; /* namespace table control: ns = 0 or 2 to start, then 1 to stop dumping the table */ +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { const char *t = strchr(tag, ':'); + if (t) + soap_utilize_ns(soap, tag, t - tag); + } +#endif + if (id > 0) + { sprintf(soap->tmpbuf, "_%d", id); + if (soap_attribute(soap, "id", soap->tmpbuf)) + return soap->error; + } + if (type && *type && (!(soap->mode & SOAP_XML_SEC) || soap->part == SOAP_IN_BODY)) + { if (soap_attribute(soap, "xsi:type", type)) + return soap->error; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { const char *t = strchr(type, ':'); + if (t) + soap_utilize_ns(soap, type, t - type); + } +#endif + } + if (soap->null && soap->position > 0) + { register int i; + sprintf(soap->tmpbuf, "[%d", soap->positions[0]); + for (i = 1; i < soap->position; i++) + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]); + strcat(soap->tmpbuf, "]"); + if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf)) + return soap->error; + } + if (soap->mustUnderstand) + { if (soap->actor && *soap->actor) + { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor)) + return soap->error; + } + if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1")) + return soap->error; + soap->mustUnderstand = 0; + } + if (soap->encoding) + { if (soap->encodingStyle && soap->local_namespaces) + { if (!*soap->encodingStyle) + { if (soap->local_namespaces[1].out) + soap->encodingStyle = soap->local_namespaces[1].out; + else + soap->encodingStyle = soap->local_namespaces[1].ns; + } + if (soap->encodingStyle && soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle)) + return soap->error; + } + soap->encoding = 0; + } + soap->null = 0; + soap->position = 0; + if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL)) + soap->part = SOAP_IN_SECURITY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type) +{ if (*tag == '-') + return SOAP_OK; + if (soap_element(soap, tag, id, type)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRRCHR +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_strrchr(const char *s, int t) +{ register char *r = NULL; + while (*s) + if (*s++ == t) + r = (char*)s - 1; + return r; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOL +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_strtol(const char *s, char **t, int b) +{ register long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { short neg = 0; + if (*s == '-') + { s++; + neg = 1; + } + else if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n >= 214748364 && (n > 214748364 || c >= '8')) + break; + n *= 10; + n += c - '0'; + s++; + } + if (neg) + n = -n; + } + else /* assume b == 16 and value is always positive */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x07FFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOUL +SOAP_FMAC1 +unsigned long +SOAP_FMAC2 +soap_strtoul(const char *s, char **t, int b) +{ unsigned long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n >= 429496729 && (n > 429496729 || c >= '6')) + break; + n *= 10; + n += c - '0'; + s++; + } + } + else /* b == 16 */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x0FFFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset) +{ if (!type || !*type) + return soap_element_begin_out(soap, tag, id, NULL); + if (soap_element(soap, tag, id, "SOAP-ENC:Array")) + return soap->error; + if (soap->version == 2) + { const char *s; + s = soap_strrchr(type, '['); + if ((size_t)(s - type) < sizeof(soap->tmpbuf)) + { strncpy(soap->tmpbuf, type, s - type); + soap->tmpbuf[s - type] = '\0'; + if (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf)) + return soap->error; + if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1))) + return soap->error; + } + } + else + { if (offset && soap_attribute(soap, "SOAP-ENC:offset", offset)) + return soap->error; + if (soap_attribute(soap, "SOAP-ENC:arrayType", type)) + return soap->error; + } +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_CANONICAL)) + { const char *s = strchr(type, ':'); + if (s) + soap_utilize_ns(soap, type, s - type); + } +#endif + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_start_end_out(struct soap *soap, const char *tag) +{ register struct soap_attribute *tp; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { struct soap_nlist *np; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->name) + { const char *s = strchr(tp->name, ':'); + if (s) + soap_utilize_ns(soap, tp->name, s - tp->name); + } + } + for (np = soap->nlist; np; np = np->next) + { if (np->index == 1 && np->ns) + { sprintf(soap->tmpbuf, "xmlns:%s", np->id); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enabling utilized binding (level=%u) %s='%s'\n", np->level, soap->tmpbuf, np->ns)); + soap_set_attr(soap, soap->tmpbuf, np->ns, 1); + np->index = 2; + } + } + } +#endif +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { register struct soap_dom_attribute **att; + att = &soap->dom->atts; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!*att) + return soap->error; + (*att)->next = NULL; + (*att)->nstr = NULL; + (*att)->name = soap_strdup(soap, tp->name); + (*att)->data = soap_strdup(soap, tp->value); + (*att)->wide = NULL; + (*att)->soap = soap; + att = &(*att)->next; + tp->visible = 0; + } + } + return SOAP_OK; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { +#ifndef WITH_LEAN + const char *s; + if ((soap->mode & SOAP_XML_DEFAULTNS) && (s = strchr(tp->name, ':'))) + { size_t n = s - tp->name; + if (soap->nlist && !strncmp(soap->nlist->id, tp->name, n) && !soap->nlist->id[n]) + s++; + else + s = tp->name; + if (soap_send(soap, " ") || soap_send(soap, s)) + return soap->error; + } + else +#endif + if (soap_send(soap, " ") || soap_send(soap, tp->name)) + return soap->error; + if (tp->visible == 2 && tp->value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, tp->value, tp->flag) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + tp->visible = 0; + } + } + if (tag) + { +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { if (soap_send_raw(soap, ">", 1) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; + } +#endif + soap->level--; /* decrement level just before /> */ + return soap_send_raw(soap, "/>", 2); + } + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_out(struct soap *soap, const char *tag) +{ +#ifndef WITH_LEAN + const char *s; +#endif + if (*tag == '-') + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag)); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + soap_pop_namespace(soap); + if (soap->mode & SOAP_XML_INDENT) + { if (!soap->body) + { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1)) + return soap->error; + } + soap->body = 0; + } + if ((soap->mode & SOAP_XML_DEFAULTNS) && (s = strchr(tag, ':'))) + { soap_pop_namespace(soap); + tag = s + 1; + } +#endif + if (soap_send_raw(soap, "error; + soap->level--; /* decrement level just before > */ + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_ref(struct soap *soap, const char *tag, int id, int href) +{ register int n = 0; + const char *s = "href"; + if (soap->version == 2) + { s = "SOAP-ENC:ref"; + n = 1; + } + sprintf(soap->href, "#_%d", href); + return soap_element_href(soap, tag, id, s, soap->href + n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val)); + if (soap_element(soap, tag, id, NULL) + || soap_attribute(soap, ref, val) + || soap_element_start_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_null(struct soap *soap, const char *tag, int id, const char *type) +{ struct soap_attribute *tp = NULL; + for (tp = soap->attributes; tp; tp = tp->next) + if (tp->visible) + break; + if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL)) + { if (soap_element(soap, tag, id, type) + || (!tp && soap_attribute(soap, "xsi:nil", "true"))) + return soap->error; + return soap_element_start_end_out(soap, tag); + } + soap->null = 1; + soap->position = 0; + soap->mustUnderstand = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_nil(struct soap *soap, const char *tag) +{ if (soap_element(soap, tag, -1, NULL) + || soap_attribute(soap, "xsi:nil", "true")) + return soap->error; + return soap_element_start_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_id(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, int n, const char *type, int t) +{ if (!p) + { soap_element_null(soap, tag, id, type); + return -1; + } +#ifndef WITH_NOIDREF + if (soap->mode & SOAP_XML_TREE) + return 0; + if (id < 0) + { struct soap_plist *pp; + if (a) + id = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + else + id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap_is_embedded(soap, pp)) + { soap_element_ref(soap, tag, 0, id); + return -1; + } + if (soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + } + return id; +#else + return 0; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_result(struct soap *soap, const char *tag) +{ if (soap->version == 2 && soap->encodingStyle) + { if (soap_element(soap, "SOAP-RPC:result", 0, NULL) + || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc) + || soap_element_start_end_out(soap, NULL) + || soap_string_out(soap, tag, 0) + || soap_element_end_out(soap, "SOAP-RPC:result")) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_check_result(struct soap *soap, const char *tag) +{ if (soap->version == 2 && soap->encodingStyle) + { soap_instring(soap, ":result", NULL, NULL, 0, 2, -1, -1); + /* just ignore content for compliance reasons, but should compare tag to element's QName value? */ + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attribute(struct soap *soap, const char *name, const char *value) +{ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attribute '%s'='%s'\n", name, value)); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && !(soap->mode & SOAP_XML_CANONICAL) && soap->dom) + { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!a) + return soap->error; + a->next = soap->dom->atts; + a->nstr = NULL; + a->name = soap_strdup(soap, name); + a->data = soap_strdup(soap, value); + a->wide = NULL; + a->soap = soap; + soap->dom->atts = a; + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { /* TODO: consider using this code to handle default namespace bindings + if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0')) + { if (name[5] == ':') + soap_push_ns(soap, name + 6, value, 0); + else + soap_push_ns(soap, "", value, 0); + } + */ + if (!strncmp(name, "xmlns:", 6)) + soap_push_ns(soap, name + 6, value, 0); + else if (soap_set_attr(soap, name, value, 1)) + return soap->error; + } + else +#endif + { if (soap_send(soap, " ") || soap_send(soap, name)) + return soap->error; + if (value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_in(struct soap *soap, const char *tag, int nillable, const char *type) +{ if (!soap_peek_element(soap)) + { if (soap->other) + return soap->error = SOAP_TAG_MISMATCH; + if (tag && *tag == '-') + return SOAP_OK; + if (!(soap->error = soap_match_tag(soap, soap->tag, tag))) + { soap->peeked = 0; + if (type && *soap->type && soap_match_tag(soap, soap->type, type)) + return soap->error = SOAP_TYPE; + if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT)) + return soap->error = SOAP_NULL; + if (soap->body) + soap->level++; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:SOAP_STR_EOS )); + } + } + else if (soap->error == SOAP_NO_TAG && tag && *tag == '-') + soap->error = SOAP_OK; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_in(struct soap *soap, const char *tag) +{ register soap_wchar c; + register char *s; + register int n = 0; + if (tag && *tag == '-') + return SOAP_OK; + if (soap->error == SOAP_NO_TAG) + soap->error = SOAP_OK; +#ifdef WITH_DOM + /* this whitespace or mixed content is significant for DOM */ + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1)) + return soap->error; + if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + } +#endif + if (soap->peeked) + { if (*soap->tag) + n++; + soap->peeked = 0; + } + do + { while (((c = soap_get(soap)) != SOAP_TT)) + { if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (c == SOAP_LT) + n++; + else if (c == '/') + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + else + soap_unget(soap, c); + } + } + } while (n--); + s = soap->tag; + n = sizeof(soap->tag); + while (soap_notblank(c = soap_get(soap))) + { if (--n > 0) + *s++ = (char)c; + } + *s = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + while (soap_blank(c)) + c = soap_get(soap); + if (c != SOAP_GT) + return soap->error = SOAP_SYNTAX_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:SOAP_STR_EOS)); +#ifndef WITH_LEAN + if (tag && (soap->mode & SOAP_XML_STRICT)) + { soap_pop_namespace(soap); + if (soap_match_tag(soap, soap->tag, tag)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n")); + return soap->error = SOAP_SYNTAX_ERROR; + } + } +#endif + soap->level--; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_attr_value(struct soap *soap, const char *name, int flag) +{ register struct soap_attribute *tp; + if (*name == '-') + return SOAP_STR_EOS; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && !soap_match_tag(soap, tp->name, name)) + break; + } + if (tp) + { if (flag == 2 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_PROHIBITED; + else + return tp->value; + } + else if (flag == 1 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_REQUIRED; + else + soap->error = SOAP_OK; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_attr(struct soap *soap, const char *name, const char *value, int flag) +{ register struct soap_attribute *tp; + if (*name == '-') + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:SOAP_STR_EOS)); + for (tp = soap->attributes; tp; tp = tp->next) + { if (!strcmp(tp->name, name)) + break; + } + if (!tp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name)); + if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name)))) + return soap->error = SOAP_EOM; + tp->ns = NULL; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_CANONICAL)) + { struct soap_attribute **tpp = &soap->attributes; + const char *s = strchr(name, ':'); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inserting attribute %s for c14n\n", name)) + if (!strncmp(name, "xmlns", 5)) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0) + break; + } + else if (!s) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0)) + break; + } + else + { int k; + for (; *tpp; tpp = &(*tpp)->next) + { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name]) + { if (!tp->ns) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p (%s)\n", name, (*tpp)->ns, (*tpp)->ns)); + tp->ns = (*tpp)->ns; + } + } + else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0))) + break; + } + } + tp->next = *tpp; + *tpp = tp; + } + else +#endif + { tp->next = soap->attributes; + soap->attributes = tp; + } + strcpy(tp->name, name); + tp->value = NULL; + } + else if (tp->visible) + { return SOAP_OK; + } + else if (value && tp->value && tp->size <= strlen(value)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value)); + SOAP_FREE(soap, tp->value); + tp->value = NULL; + tp->ns = NULL; + } + if (value) + { if (!tp->value) + { tp->size = strlen(value) + 1; + if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size))) + return soap->error = SOAP_EOM; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value for %s (%p)\n", tp->name, tp->value)); + } + strcpy(tp->value, value); + if (!strncmp(tp->name, "xmlns:", 6)) + tp->ns = tp->value; + tp->visible = 2; + tp->flag = flag; +#ifndef WITH_LEAN + if (soap->part != SOAP_IN_SECURITY && !strcmp(name, "wsu:Id")) + { soap->part = SOAP_BEGIN_SECURITY; + strncpy(soap->id, value, sizeof(soap->id)); + soap->id[sizeof(soap->id)-1] = '\0'; + } +#endif + } + else + tp->visible = 1; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_attr(struct soap *soap) +{ register struct soap_attribute *tp; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_CANONICAL)) + { while (soap->attributes) + { tp = soap->attributes->next; + if (soap->attributes->value) + SOAP_FREE(soap, soap->attributes->value); + SOAP_FREE(soap, soap->attributes); + soap->attributes = tp; + } + } + else +#endif + { for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d) +{ register size_t i; + for (i = 0; i < n; i++) + { register soap_wchar c = soap_get(soap); + switch (c) + { + case SOAP_TT: + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + *s++ = '<'; + break; + case SOAP_GT: + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + *s++ = '>'; + break; + case SOAP_QT: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '"'; + break; + case SOAP_AP: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '\''; + break; + case '\t': + case '\n': + case '\r': + case ' ': + case '/': + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + default: + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + } + return soap->error = SOAP_EOM; +} +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_store_lab(struct soap *soap, const char *s, size_t n) +{ soap->labidx = 0; + return soap_append_lab(soap, s, n); +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_append_lab(struct soap *soap, const char *s, size_t n) +{ if (soap->labidx + n >= soap->lablen) + { register char *t = soap->labbuf; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen)); + if (soap->lablen == 0) + soap->lablen = SOAP_LABLEN; + while (soap->labidx + n >= soap->lablen) + soap->lablen <<= 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen)); + soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen); + if (!soap->labbuf) + { if (t) + SOAP_FREE(soap, t); + return soap->error = SOAP_EOM; + } + if (t) + { memcpy(soap->labbuf, t, soap->labidx); + SOAP_FREE(soap, t); + } + } + if (s) + { memcpy(soap->labbuf + soap->labidx, s, n); + soap->labidx += n; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_peek_element(struct soap *soap) +{ +#ifdef WITH_DOM + register struct soap_dom_attribute **att = NULL; + register char *lead = NULL; +#endif + register struct soap_attribute *tp, *tq = NULL; + register const char *t; + register char *s; + register soap_wchar c; + register int i; + if (soap->peeked) + { if (!*soap->tag) + return soap->error = SOAP_NO_TAG; + return SOAP_OK; + } + soap->peeked = 1; + soap->id[0] = '\0'; + soap->href[0] = '\0'; + soap->type[0] = '\0'; + soap->arrayType[0] = '\0'; + soap->arraySize[0] = '\0'; + soap->arrayOffset[0] = '\0'; + soap->other = 0; + soap->root = -1; + soap->position = 0; + soap->null = 0; + soap->mustUnderstand = 0; + /* skip BOM */ + if ((c = soap_getchar(soap)) != 0xEF || (c = soap_get1(soap)) != 0xBB || (c = soap_get1(soap)) != 0xBF) + soap_unget(soap, c); + c = soap_get(soap); +#ifdef WITH_DOM + /* whitespace leading to tag is not insignificant for DOM */ + if (soap_blank(c)) + { soap->labidx = 0; + do + { if (soap_append_lab(soap, NULL, 0)) + return soap->error; + s = soap->labbuf + soap->labidx; + i = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + while (soap_blank(c) && i--) + { *s++ = c; + c = soap_get(soap); + } + } + while (soap_blank(c)); + *s = '\0'; + lead = soap->labbuf; + } +#else + /* skip space */ + while (soap_blank(c)) + c = soap_get(soap); +#endif + if (c != SOAP_LT) + { *soap->tag = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifdef WITH_DOM + /* whitespace leading to end tag is significant for DOM */ + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (lead && *lead) + soap->dom->tail = soap_strdup(soap, lead); + else + soap->dom->tail = (char*)SOAP_STR_EOS; + } +#endif + return soap->error = SOAP_NO_TAG; + } + s = soap->tag; + do c = soap_get1(soap); + while (soap_blank(c)); + i = sizeof(soap->tag); + while (c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF) + { if (--i > 0) + *s++ = (char)c; + c = soap_get1(soap); + } + while (soap_blank(c)) + c = soap_get1(soap); + *s = '\0'; +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *elt; + elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + if (!elt) + return soap->error; + elt->next = NULL; + elt->nstr = NULL; + elt->name = soap_strdup(soap, soap->tag); + elt->prnt = soap->dom; + elt->elts = NULL; + elt->atts = NULL; + elt->data = NULL; + elt->wide = NULL; + elt->type = 0; + elt->node = NULL; + elt->head = soap_strdup(soap, lead); + elt->tail = NULL; + elt->soap = soap; + if (soap->dom) + { struct soap_dom_element *p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = elt; + } + else + soap->dom->elts = elt; + } + soap->dom = elt; + att = &elt->atts; + } +#endif + soap_pop_namespace(soap); + for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + while ((int)c != EOF && c != '>' && c != '/') + { s = soap->tmpbuf; + i = sizeof(soap->tmpbuf); + while (c != '=' && c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF) + { if (--i > 0) + *s++ = (char)c; + c = soap_get1(soap); + } + *s = '\0'; + if (i == sizeof(soap->tmpbuf)) + return soap->error = SOAP_SYNTAX_ERROR; +#ifdef WITH_DOM + /* add attribute name to dom */ + if (att) + { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!*att) + return soap->error; + (*att)->next = NULL; + (*att)->nstr = NULL; + (*att)->name = soap_strdup(soap, soap->tmpbuf); + (*att)->data = NULL; + (*att)->wide = NULL; + (*att)->soap = soap; + } +#endif + if (!strncmp(soap->tmpbuf, "xmlns", 5)) + { if (soap->tmpbuf[5] == ':') + t = soap->tmpbuf + 6; + else if (soap->tmpbuf[5]) + t = NULL; + else + t = SOAP_STR_EOS; + } + else + t = NULL; + tq = NULL; + for (tp = soap->attributes; tp; tq = tp, tp = tp->next) + { if (!SOAP_STRCMP(tp->name, soap->tmpbuf)) + break; + } + if (!tp) + { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf)); + if (!tp) + return soap->error = SOAP_EOM; + strcpy(tp->name, soap->tmpbuf); + tp->value = NULL; + tp->size = 0; + /* if attribute name is qualified, append it to the end of the list */ + if (tq && strchr(soap->tmpbuf, ':')) + { tq->next = tp; + tp->next = NULL; + } + else + { tp->next = soap->attributes; + soap->attributes = tp; + } + } + while (soap_blank(c)) + c = soap_get1(soap); + if (c == '=') + { do c = soap_getutf8(soap); + while (soap_blank(c)); + if (c != SOAP_QT && c != SOAP_AP) + { soap_unget(soap, c); + c = ' '; /* blank delimiter */ + } + if (soap_getattrval(soap, tp->value, tp->size, c)) + { +#ifdef WITH_FAST + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_store_lab(soap, tp->value, tp->size)) + return soap->error; + if (tp->value) + SOAP_FREE(soap, tp->value); + for (;;) + { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + soap->labidx = soap->lablen; + if (soap_append_lab(soap, NULL, 0)) + return soap->error; + } + else + break; + } + if (soap->labidx) + tp->size = soap->lablen; + else + { tp->size = strlen(soap->labbuf) + 1; + if (tp->size < SOAP_LABLEN) + tp->size = SOAP_LABLEN; + } + if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size))) + return soap->error = SOAP_EOM; + strcpy(tp->value, soap->labbuf); +#else + size_t n; + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_new_block(soap) == NULL) + return soap->error; + for (;;) + { if (!(s = (char*)soap_push_block(soap, NULL, SOAP_BLKLEN))) + return soap->error; + if (soap_getattrval(soap, s, SOAP_BLKLEN, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + } + else + break; + } + n = tp->size + soap->blist->size; + if (!(s = (char*)SOAP_MALLOC(soap, n))) + return soap->error = SOAP_EOM; + if (tp->value) + { memcpy(s, tp->value, tp->size); + SOAP_FREE(soap, tp->value); + } + soap_save_block(soap, NULL, s + tp->size, 0); + tp->value = s; + tp->size = n; +#endif + } + do c = soap_get1(soap); + while (soap_blank(c)); + tp->visible = 2; /* seen this attribute w/ value */ +#ifdef WITH_DOM + if (att) + (*att)->data = soap_strdup(soap, tp->value); +#endif + } + else + tp->visible = 1; /* seen this attribute w/o value */ +#ifdef WITH_DOM + if (att) + att = &(*att)->next; +#endif + if (t && tp->value) + { if (soap_push_namespace(soap, t, tp->value) == NULL) + return soap->error; + } + } +#ifdef WITH_DOM + if (att) + { soap->dom->nstr = soap_current_namespace(soap, soap->tag); + for (att = &soap->dom->atts; *att; att = &(*att)->next) + (*att)->nstr = soap_current_namespace(soap, (*att)->name); + } +#endif + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (!(soap->body = (c != '/'))) + do c = soap_get1(soap); + while (soap_blank(c)); +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { if (!soap->body && soap->dom->prnt) + soap->dom = soap->dom->prnt; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->value) + { +#ifndef WITH_NOIDREF + if (!strcmp(tp->name, "id")) + { if ((soap->version > 0 && !(soap->mode & SOAP_XML_TREE)) + || (soap->mode & SOAP_XML_GRAPH)) + { *soap->id = '#'; + strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2); + soap->id[sizeof(soap->id)-1] = '\0'; + } + } + else if (!strcmp(tp->name, "href")) + { if (soap->version == 1 + || (soap->mode & SOAP_XML_GRAPH) + || (soap->mode & SOAP_ENC_MTOM) + || (soap->mode & SOAP_ENC_DIME)) + { strncpy(soap->href, tp->value, sizeof(soap->href) - 1); + soap->href[sizeof(soap->href)-1] = '\0'; + } + } + else +#endif + if (!soap_match_tag(soap, tp->name, "xsi:type")) + { strncpy(soap->type, tp->value, sizeof(soap->type) - 1); + soap->type[sizeof(soap->type)-1] = '\0'; + } + else if ((!soap_match_tag(soap, tp->name, "xsi:null") + || !soap_match_tag(soap, tp->name, "xsi:nil")) + && (!strcmp(tp->value, "1") + || !strcmp(tp->value, "true"))) + { soap->null = 1; + } + else if (soap->version == 1) + { if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType")) + { s = soap_strrchr(tp->value, '['); + if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType)) + { strncpy(soap->arrayType, tp->value, s - tp->value); + soap->arrayType[s - tp->value] = '\0'; + strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1); + } + else + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + soap->arraySize[sizeof(soap->arrayType)-1] = '\0'; + soap->arrayType[sizeof(soap->arrayType)-1] = '\0'; + } + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:offset")) + strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset)); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:position")) + soap->position = soap_getposition(tp->value, soap->positions); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:root")) + soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand") + && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))) + soap->mustUnderstand = 1; + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:actor")) + { if ((!soap->actor || strcmp(soap->actor, tp->value)) + && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next")) + soap->other = 1; + } + } + else if (soap->version == 2) + { +#ifndef WITH_NOIDREF + if (!strcmp(tp->name, "ref") + || !soap_match_tag(soap, tp->name, "SOAP-ENC:ref")) + { *soap->href = '#'; + strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2); + soap->href[sizeof(soap->href)-1] = '\0'; + } + else +#endif + if (!soap_match_tag(soap, tp->name, "SOAP-ENC:itemType")) + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize")) + strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand") + && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))) + soap->mustUnderstand = 1; + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:role")) + { if ((!soap->actor || strcmp(soap->actor, tp->value)) + && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next")) + soap->other = 1; + } + } + else + { if (!soap_match_tag(soap, tp->name, "wsdl:required") && !strcmp(tp->value, "true")) + soap->mustUnderstand = 1; + } + } + } + return soap->error = SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_retry(struct soap *soap) +{ soap->error = SOAP_OK; + soap_revert(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_revert(struct soap *soap) +{ if (!soap->peeked) + { soap->peeked = 1; + if (soap->body) + soap->level--; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting to last element '%s' (level=%u)\n", soap->tag, soap->level)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_string_out(struct soap *soap, const char *s, int flag) +{ register const char *t; + register soap_wchar c; + register soap_wchar mask = (soap_wchar)0xFFFFFF80UL; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_strdup(soap, s); + return SOAP_OK; + } +#endif + if (flag == 2 || soap->mode & SOAP_C_UTFSTRING) + mask = 0; + t = s; + while ((c = *t++)) + { switch (c) + { + case 0x09: + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 0x0A: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 0x0D: + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + break; + case '&': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&", 5)) + return soap->error; + s = t; + break; + case '<': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "<", 4)) + return soap->error; + s = t; + break; + case '>': + if (!flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, ">", 4)) + return soap->error; + s = t; + } + break; + case '"': + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, """, 6)) + return soap->error; + s = t; + } + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_MBTOWC + if (soap->mode & SOAP_C_MBSTRING) + { wchar_t wc; + register int m = mbtowc(&wc, t - 1, MB_CUR_MAX); + if (m > 0 && wc != c) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc)) + return soap->error; + s = t += m - 1; + continue; + } + } +#endif +#endif +#ifndef WITH_NOSTRINGTOUTF8 + if ((c & mask) || !(c & 0xFFFFFFE0UL)) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c)) + return soap->error; + s = t; + } +#endif + } + } + return soap_send_raw(soap, s, t - s - 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) +{ register char *s; + char *t = NULL; + register size_t i; + register long l = 0; + register int n = 0, f = 0, m = 0; + register soap_wchar c; +#if !defined(WITH_LEANER) && defined(HAVE_WCTOMB) + char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8]; +#else + char buf[8]; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content, flag=%d\n", flag)); + if (soap->peeked && *soap->tag) + { +#ifndef WITH_LEAN + struct soap_attribute *tp; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String content includes tag '%s' and attributes\n", soap->tag)); + t = soap->tmpbuf; + *t = '<'; + t[sizeof(soap->tmpbuf)-1] = '\0'; + strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 2); + t += strlen(t); + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2) + break; + *t++ = ' '; + strcpy(t, tp->name); + t += strlen(t); + if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2) + break; /* too many or large attribute values */ + if (tp->value) + { *t++ = '='; + *t++ = '"'; + strcpy(t, tp->value); + t += strlen(t); + *t++ = '"'; + } + } + } + if (!soap->body) + *t++ = '/'; + *t++ = '>'; + *t = '\0'; + t = soap->tmpbuf; + m = (int)strlen(soap->tmpbuf); +#endif + if (soap->body) + n = 1; + f = 1; + soap->peeked = 0; + } +#ifdef WITH_CDATA + if (!flag) + { register int state = 0; +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap) == NULL) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, NULL, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + c = soap_getchar(soap); + if ((int)c == EOF) + goto end; + if (c >= 0x80 && state != 1 && !(soap->mode & SOAP_ENC_LATIN)) + { soap_unget(soap, c); + c = soap_getutf8(soap); + if (soap->mode & SOAP_C_UTFSTRING) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + switch (state) + { case 1: + if (c == ']') + state = 4; + *s++ = c; + continue; + case 2: + if (c == '-') + state = 6; + *s++ = c; + continue; + case 3: + if (c == '?') + state = 8; + *s++ = c; + continue; + /* CDATA */ + case 4: + if (c == ']') + state = 5; + else + state = 1; + *s++ = c; + continue; + case 5: + if (c == '>') + state = 0; + else + state = 1; + *s++ = c; + continue; + /* comment */ + case 6: + if (c == '-') + state = 7; + else + state = 2; + *s++ = c; + continue; + case 7: + if (c == '>') + state = 0; + else + state = 2; + *s++ = c; + continue; + /* PI */ + case 8: + if (c == '>') + state = 0; + else + state = 3; + *s++ = c; + continue; + } + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + t = (char*)"/"; + m = 1; + break; + case SOAP_LT: + if (f && n == 0) + goto end; + n++; + *s++ = '<'; + break; + case '/': + if (n > 0) + { c = soap_getchar(soap); + if (c == '>') + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + c = soap_getchar(soap); + if (c == '/') + { if (n == 0) + { c = SOAP_TT; + goto end; + } + n--; + } + else if (c == '!') + { c = soap_getchar(soap); + if (c == '[') + { do c = soap_getchar(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + goto end; + t = (char*)"![CDATA["; + m = 8; + state = 1; + } + else if (c == '-') + { if ((c = soap_getchar(soap)) == '-') + state = 2; + t = (char*)"!-"; + m = 2; + soap_unget(soap, c); + } + else + { t = (char*)"!"; + m = 1; + soap_unget(soap, c); + } + *s++ = '<'; + break; + } + else if (c == '?') + state = 3; + else if (f && n == 0) + { soap_revget1(soap); + c = '<'; + goto end; + } + else + n++; + soap_unget(soap, c); + *s++ = '<'; + break; + case '>': + *s++ = '>'; + break; + case '"': + *s++ = '"'; + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1 && m <= (int)MB_CUR_MAX) + { t = buf; + *s++ = *t++; + m--; + } + else + { *s++ = SOAP_UNKNOWN_CHAR; + m = 0; + } + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if (maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap) == NULL) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, NULL, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + if (soap->mode & SOAP_C_UTFSTRING) + { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + else + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + t = (char*)"/"; + m = 1; + break; + case SOAP_LT: + if (f && n == 0) + goto end; + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case (soap_wchar)('<' | 0x80000000): + if (flag) + *s++ = '<'; + else + { *s++ = '&'; + t = (char*)"lt;"; + m = 3; + } + break; + case (soap_wchar)('>' | 0x80000000): + if (flag) + *s++ = '>'; + else + { *s++ = '&'; + t = (char*)"gt;"; + m = 3; + } + break; + case (soap_wchar)('&' | 0x80000000): + if (flag) + *s++ = '&'; + else + { *s++ = '&'; + t = (char*)"amp;"; + m = 4; + } + break; + case (soap_wchar)('"' | 0x80000000): + if (flag) + *s++ = '"'; + else + { *s++ = '&'; + t = (char*)"quot;"; + m = 5; + } + break; + case (soap_wchar)('\'' | 0x80000000): + if (flag) + *s++ = '\''; + else + { *s++ = '&'; + t = (char*)"apos;"; + m = 5; + } + break; + default: + if ((int)c == EOF) + goto end; +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1 && m <= (int)MB_CUR_MAX) + { t = buf; + *s++ = *t++; + m--; + } + else + { *s++ = SOAP_UNKNOWN_CHAR; + m = 0; + } + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if (maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; +#ifdef WITH_FAST + t = soap_strdup(soap, soap->labbuf); +#else + soap_size_block(soap, NULL, i+1); + t = soap_save_block(soap, NULL, 0); +#endif + if (l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (flag == 3) + soap->dom->tail = t; + else + soap->dom->data = t; + } +#endif + if (flag == 2) + if (soap_s2QName(soap, t, &t, minlen, maxlen)) + return NULL; + return t; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_wstring_out(struct soap *soap, const wchar_t *s, int flag) +{ const char *t; + char tmp; + register soap_wchar c; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { wchar_t *r = (wchar_t*)s; + int n = 1; + while (*r++) + n++; + soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t)); + while (n--) + *r++ = *s++; + return SOAP_OK; + } +#endif + while ((c = *s++)) + { switch (c) + { + case 0x09: + if (flag) + t = " "; + else + t = "\t"; + break; + case 0x0A: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + t = " "; + else + t = "\n"; + break; + case 0x0D: + t = " "; + break; + case '&': + t = "&"; + break; + case '<': + t = "<"; + break; + case '>': + if (flag) + t = ">"; + else + t = ">"; + break; + case '"': + if (flag) + t = """; + else + t = "\""; + break; + default: + if (c >= 0x20 && c < 0x80) + { tmp = (char)c; + if (soap_send_raw(soap, &tmp, 1)) + return soap->error; + } + else /* check UTF16 encoding when wchar_t is too small to hold UCS */ + { if (sizeof(wchar_t) < 4 && (c & 0xD800) == 0xD800) + { /* http://unicode.org/faq/utf_bom.html#utf16-2 */ + if ((*s & 0xD800) == 0xD800) + c = (c << 10) + *s++ + 0x10000 - (0xD800 << 10) - 0xDC00; + else + c = 0xFFFD; /* Malformed */ + } + if (soap_pututf8(soap, (unsigned long)c)) + return soap->error; + } + continue; + } + if (soap_send(soap, t)) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t * +SOAP_FMAC2 +soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen) +{ wchar_t *s; + register int i, n = 0, f = 0; + register long l = 0; + register soap_wchar c; + char *t = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n")); + if (soap->peeked) + { if (*soap->tag) + { +#ifndef WITH_LEAN + struct soap_attribute *tp; + t = soap->tmpbuf; + *t = '<'; + t[sizeof(soap->tmpbuf)-1] = '\0'; + strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 2); + t += strlen(t); + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2) + break; + *t++ = ' '; + strcpy(t, tp->name); + t += strlen(t); + if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2) + break; + if (tp->value) + { *t++ = '='; + *t++ = '"'; + strcpy(t, tp->value); + t += strlen(t); + *t++ = '"'; + } + } + } + if (!soap->body) + *t++ = '/'; + *t++ = '>'; + *t = '\0'; + t = soap->tmpbuf; +#endif + if (soap->body) + n = 1; + f = 1; + soap->peeked = 0; + } + } + if (soap_new_block(soap) == NULL) + return NULL; + for (;;) + { if (!(s = (wchar_t*)soap_push_block(soap, NULL, sizeof(wchar_t)*SOAP_BLKLEN))) + return NULL; + for (i = 0; i < SOAP_BLKLEN; i++) + { if (t) + { *s++ = (wchar_t)*t++; + if (!*t) + t = NULL; + continue; + } + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + if (f && n == 0) + goto end; + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_getutf8(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + if (flag) + *s++ = (soap_wchar)'<'; + else + { *s++ = (soap_wchar)'&'; + t = (char*)"lt;"; + } + break; + case '>': + if (flag) + *s++ = (soap_wchar)'>'; + else + { *s++ = (soap_wchar)'&'; + t = (char*)"gt;"; + } + break; + case '"': + if (flag) + *s++ = (soap_wchar)'"'; + else + { *s++ = (soap_wchar)'&'; + t = (char*)"quot;"; + } + break; + default: + if ((int)c == EOF) + goto end; + if (sizeof(wchar_t) < 4 && c > 0xFFFF) + { wchar_t c1, c2; + /* http://unicode.org/faq/utf_bom.html#utf16-2 */ + c1 = 0xD800 - (0x10000 >> 10) + (c >> 10); + c2 = 0xDC00 + (c & 0x3FF); + c = c1; + soap_unget(soap, c2); + } + *s++ = (wchar_t)c & 0x7FFFFFFF; + } + l++; + if (maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; + soap_size_block(soap, NULL, sizeof(wchar_t) * (i + 1)); + if (l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + s = (wchar_t*)soap_save_block(soap, NULL, NULL, 0); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->wide = s; +#endif + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_int2s(struct soap *soap, int n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2int(struct soap *soap, const char *s, int *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = (int)soap_strtol(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int * +SOAP_FMAC2 +soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL); + if (*soap->href) + p = (int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(int), 0, NULL); + else if (p) + { if (soap_s2int(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_long2s(struct soap *soap, long n) +{ sprintf(soap->tmpbuf, "%ld", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2long(struct soap *soap, const char *s, long *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = soap_strtol(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +long * +SOAP_FMAC2 +soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL); + if (*soap->href) + p = (long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(long), 0, NULL); + else if (p) + { if (soap_s2long(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_LONG642s(struct soap *soap, LONG64 n) +{ sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_LONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p) +{ if (s) + { +#ifdef HAVE_STRTOLL + char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = strtoll(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) +#else +# ifdef HAVE_SSCANF + if (sscanf(s, SOAP_LONG_FORMAT, p) != 1) +# endif +#endif + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +LONG64 * +SOAP_FMAC2 +soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL); + if (*soap->href) + p = (LONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(LONG64), 0, NULL); + else if (p) + { if (soap_s2LONG64(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_byte2s(struct soap *soap, char n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outbyte(struct soap *soap, const char *tag, int id, const char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2byte(struct soap *soap, const char *s, char *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (s == r || *r || n < -128 || n > 127) + soap->error = SOAP_TYPE; + *p = (char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL); + if (*soap->href) + p = (char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(char), 0, NULL); + else if (p) + { if (soap_s2byte(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_short2s(struct soap *soap, short n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outshort(struct soap *soap, const char *tag, int id, const short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2short(struct soap *soap, const char *s, short *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (s == r || *r || n < -32768 || n > 32767) + soap->error = SOAP_TYPE; + *p = (short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +short * +SOAP_FMAC2 +soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL); + if (*soap->href) + p = (short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(short), 0, NULL); + else if (p) + { if (soap_s2short(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_float2s(struct soap *soap, float n) +{ char *s; + if (soap_isnan((double)n)) + return "NaN"; + if (soap_ispinff(n)) + return "INF"; + if (soap_isninff(n)) + return "-INF"; + s = soap->tmpbuf; +#if defined(HAVE_SPRINTF_L) + sprintf_l(s, soap->c_locale, soap->float_format, n); +#else + sprintf(s, soap->float_format, n); + s = strchr(s, ','); /* convert decimal comma to DP */ + if (s) + *s = '.'; +#endif + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outfloat(struct soap *soap, const char *tag, int id, const float *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_float2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2float(struct soap *soap, const char *s, float *p) +{ if (s) + { if (!*s) + return soap->error = SOAP_TYPE; + if (!soap_tag_cmp(s, "INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = FLT_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = FLT_NAN; + else + { +/* On some systems strtof requires -std=c99 or does not even link: so we try to use strtod first */ +#if defined(HAVE_STRTOD_L) + char *r; + *p = (float)strtod_l(s, &r, soap->c_locale); + if (*r) +#elif defined(HAVE_STRTOD) + char *r; + *p = (float)strtod(s, &r); + if (*r) +#elif defined(HAVE_STRTOF_L) + char *r; + *p = strtof_l((char*)s, &r, soap->c_locale); + if (*r) +#elif defined(HAVE_STRTOF) + char *r; + *p = strtof((char*)s, &r); + if (*r) +#endif + { +#if defined(HAVE_SSCANF_L) && !defined(HAVE_STRTOF_L) && !defined(HAVE_STRTOD_L) + if (sscanf_l(s, soap->c_locale, "%g", p) != 1) + soap->error = SOAP_TYPE; +#elif defined(HAVE_SSCANF) + if (sscanf(s, "%g", p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static int soap_isnumeric(struct soap *soap, const char *type) +{ if (soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":float") + && soap_match_tag(soap, soap->type, ":double") + && soap_match_tag(soap, soap->type, ":decimal") + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return SOAP_ERR; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +float * +SOAP_FMAC2 +soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL); + if (*soap->href) + p = (float*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(float), 0, NULL); + else if (p) + { if (soap_s2float(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_double2s(struct soap *soap, double n) +{ char *s; + if (soap_isnan(n)) + return "NaN"; + if (soap_ispinfd(n)) + return "INF"; + if (soap_isninfd(n)) + return "-INF"; + s = soap->tmpbuf; +#if defined(HAVE_SPRINTF_L) + sprintf_l(s, soap->c_locale, soap->double_format, n); +#else + sprintf(s, soap->double_format, n); + s = strchr(s, ','); /* convert decimal comma to DP */ + if (s) + *s = '.'; +#endif + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdouble(struct soap *soap, const char *tag, int id, const double *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_double2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2double(struct soap *soap, const char *s, double *p) +{ if (s) + { if (!*s) + return soap->error = SOAP_TYPE; + if (!soap_tag_cmp(s, "INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = DBL_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = DBL_NAN; + else + { +#if defined(HAVE_STRTOD_L) + char *r; + *p = strtod_l(s, &r, soap->c_locale); + if (*r) +#elif defined(HAVE_STRTOD) + char *r; + *p = strtod(s, &r); + if (*r) +#endif + { +#if defined(HAVE_SSCANF_L) && !defined(HAVE_STRTOF_L) && !defined(HAVE_STRTOD_L) + if (sscanf_l(s, soap->c_locale, "%lg", p) != 1) + soap->error = SOAP_TYPE; +#elif defined(HAVE_SSCANF) + if (sscanf(s, "%lg", p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +double * +SOAP_FMAC2 +soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL); + if (*soap->href) + p = (double*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(double), 0, NULL); + else if (p) + { if (soap_s2double(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedByte2s(struct soap *soap, unsigned char n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedByte(struct soap *soap, const char *s, unsigned char *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (s == r || *r || n > 255) + soap->error = SOAP_TYPE; + *p = (unsigned char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned char * +SOAP_FMAC2 +soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned char), 0, NULL); + else if (p) + { if (soap_s2unsignedByte(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedShort2s(struct soap *soap, unsigned short n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedShort(struct soap *soap, const char *s, unsigned short *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (s == r || *r || n > 65535) + soap->error = SOAP_TYPE; + *p = (unsigned short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned short * +SOAP_FMAC2 +soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned short), 0, NULL); + else if (p) + { if (soap_s2unsignedShort(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedInt2s(struct soap *soap, unsigned int n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedInt(struct soap *soap, const char *s, unsigned int *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = (unsigned int)soap_strtoul(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned int * +SOAP_FMAC2 +soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned int), 0, NULL); + else if (p) + { if (soap_s2unsignedInt(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedLong2s(struct soap *soap, unsigned long n) +{ sprintf(soap->tmpbuf, "%lu", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedLong(struct soap *soap, const char *tag, int id, const unsigned long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedLong(struct soap *soap, const char *s, unsigned long *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = soap_strtoul(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned long * +SOAP_FMAC2 +soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned long), 0, NULL); + else if (p) + { if (soap_s2unsignedLong(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_ULONG642s(struct soap *soap, ULONG64 n) +{ sprintf(soap->tmpbuf, SOAP_ULONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outULONG64(struct soap *soap, const char *tag, int id, const ULONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_ULONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p) +{ if (s) + { +#ifdef HAVE_STRTOULL + char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = strtoull(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) +#else +#ifdef HAVE_SSCANF + if (sscanf(s, SOAP_ULONG_FORMAT, p) != 1) +#endif +#endif + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +ULONG64 * +SOAP_FMAC2 +soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL); + if (*soap->href) + p = (ULONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(ULONG64), 0, NULL); + else if (p) + { if (soap_s2ULONG64(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2string(struct soap *soap, const char *s, char **t, long minlen, long maxlen) +{ if (s) + { long l = (long)strlen(s); + if ((maxlen >= 0 && l > maxlen) || l < minlen) + return soap->error = SOAP_LENGTH; + if (!(*t = soap_strdup(soap, s))) + return soap->error = SOAP_EOM; + if (!(soap->mode & (SOAP_ENC_LATIN | SOAP_C_UTFSTRING))) + { char *r = *t; + /* remove non-ASCII chars */ + for (s = *t; *s; s++) + if (!(*s & 0x80)) + *r++ = *s; + *r = '\0'; + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2QName(struct soap *soap, const char *s, char **t, long minlen, long maxlen) +{ if (s) + { long l = (long)strlen(s); + if ((maxlen >= 0 && l > maxlen) || l < minlen) + return soap->error = SOAP_LENGTH; + soap->labidx = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Normalized namespace(s) of QNames '%s'", s)); + /* convert (by prefix normalize prefix) all QNames in s */ + for (;;) + { size_t n; + struct soap_nlist *np; + register const char *p; + /* skip blanks */ + while (*s && soap_blank((soap_wchar)*s)) + s++; + if (!*s) + break; + /* find next QName */ + n = 1; + while (s[n] && !soap_blank(s[n])) + n++; + np = soap->nlist; + /* if there is no namespace stack, or prefix is "xml" then copy string */ + if (!np || !strncmp(s, "xml:", 4)) + { soap_append_lab(soap, s, n); + } + else /* we normalize the QName by replacing its prefix */ + { const char *q; + for (p = s; *p && p < s + n; p++) + if (*p == ':') + break; + if (*p == ':') + { size_t k = p - s; + while (np && (strncmp(np->id, s, k) || np->id[k])) + np = np->next; + p++; + } + else + { while (np && *np->id) + np = np->next; + p = s; + } + /* replace prefix */ + if (np) + { if (np->index >= 0 && soap->local_namespaces && (q = soap->local_namespaces[np->index].id)) + { size_t k = strlen(q); + if (q[k-1] != '_') + soap_append_lab(soap, q, k); + else + { soap_append_lab(soap, "\"", 1); + soap_append_lab(soap, soap->local_namespaces[np->index].ns, strlen(soap->local_namespaces[np->index].ns)); + soap_append_lab(soap, "\"", 1); + } + } + else if (np->ns) + { soap_append_lab(soap, "\"", 1); + soap_append_lab(soap, np->ns, strlen(np->ns)); + soap_append_lab(soap, "\"", 1); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nNamespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:SOAP_STR_EOS)); + return soap->error = SOAP_NAMESPACE; + } + } + else if (s[n]) /* no namespace, part of string */ + { soap_append_lab(soap, s, n); + } + else /* no namespace: assume "" namespace */ + { soap_append_lab(soap, "\"\"", 2); + } + soap_append_lab(soap, ":", 1); + soap_append_lab(soap, p, n - (p-s)); + } + /* advance to next and add spacing */ + s += n; + if (*s) + soap_append_lab(soap, " ", 1); + } + soap_append_lab(soap, SOAP_STR_EOS, 1); + *t = soap_strdup(soap, soap->labbuf); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, " into '%s'\n", *t)); + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_QName2s(struct soap *soap, const char *s) +{ const char *t = NULL; + if (s) + { soap->labidx = 0; + for (;;) + { size_t n; + /* skip blanks */ + while (*s && soap_blank((soap_wchar)*s)) + s++; + if (!*s) + break; + /* find next QName */ + n = 1; + while (s[n] && !soap_blank((soap_wchar)s[n])) + n++; + /* normal prefix: pass string as is */ + if (*s != '"') + { soap_append_lab(soap, s, n); +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_CANONICAL)) + { const char *r = strchr(s, ':'); + if (r) + soap_utilize_ns(soap, s, r - s); + } +#endif + } + else /* URL-based string prefix */ + { const char *q; + s++; + q = strchr(s, '"'); + if (q) + { struct Namespace *p = soap->local_namespaces; + if (p) + { for (; p->id; p++) + { if (p->ns) + if (!soap_tag_cmp(s, p->ns)) + break; + if (p->in) + if (!soap_tag_cmp(s, p->in)) + break; + } + } + /* URL is in the namespace table? */ + if (p && p->id) + { soap_append_lab(soap, p->id, strlen(p->id)); + } + else /* not in namespace table: create xmlns binding */ + { char *r = soap_strdup(soap, s); + r[q-s] = '\0'; + sprintf(soap->tmpbuf, "xmlns:_%d", soap->idnum++); + soap_set_attr(soap, soap->tmpbuf, r, 1); + soap_append_lab(soap, soap->tmpbuf + 6, strlen(soap->tmpbuf + 6)); + } + soap_append_lab(soap, q + 1, n - (q-s) - 1); + } + } + /* advance to next and add spacing */ + s += n; + if (*s) + soap_append_lab(soap, " ", 1); + } + soap_append_lab(soap, SOAP_STR_EOS, 1); + t = soap_strdup(soap, soap->labbuf); + } + return t; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2wchar(struct soap *soap, const char *s, wchar_t **t, long minlen, long maxlen) +{ if (s) + { long l; + wchar_t *r; + *t = r = (wchar_t*)soap_malloc(soap, sizeof(wchar_t) * (strlen(s) + 1)); + if (!r) + return soap->error = SOAP_EOM; + if (soap->mode & SOAP_ENC_LATIN) + { while (*s) + *r++ = (wchar_t)*s++; + } + else + { /* Convert UTF8 to wchar */ + while (*s) + { register soap_wchar c, c1, c2, c3, c4; + c = (unsigned char)*s++; + if (c < 0x80) + *r++ = (wchar_t)c; + else + { c1 = (soap_wchar)*s++ & 0x3F; + if (c < 0xE0) + *r++ = (wchar_t)(((soap_wchar)(c & 0x1F) << 6) | c1); + else + { c2 = (soap_wchar)*s++ & 0x3F; + if (c < 0xF0) + *r++ = (wchar_t)(((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2); + else + { c3 = (soap_wchar)*s++ & 0x3F; + if (c < 0xF8) + *r++ = (wchar_t)(((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3); + else + { c4 = (soap_wchar)*s++ & 0x3F; + if (c < 0xFC) + *r++ = (wchar_t)(((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4); + else + *r++ = (wchar_t)(((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(*s++ & 0x3F)); + } + } + } + } + } + } + *r = L'\0'; + l = (long)(r - *t); + if ((maxlen >= 0 && l > maxlen) || l < minlen) + return soap->error = SOAP_LENGTH; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_wchar2s(struct soap *soap, const wchar_t *s) +{ register soap_wchar c; + register char *r, *t; + const wchar_t *q = s; + size_t n = 0; + while ((c = *q++)) + { if (c > 0 && c < 0x80) + n++; + else + n += 6; + } + r = t = (char*)soap_malloc(soap, n + 1); + if (r) + { /* Convert wchar to UTF8 */ + while ((c = *s++)) + { if (c > 0 && c < 0x80) + *t++ = (char)c; + else + { if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + } + } + *t = '\0'; + } + return r; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0) + return soap->error; + if (!**p && (soap->mode & SOAP_C_NILSTRING)) + return soap_element_null(soap, tag, id, type); + if (soap_element_begin_out(soap, tag, id, type) + || soap_string_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + { if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + } + if (soap->null) + *p = NULL; + else if (soap->body) + { *p = soap_string_in(soap, flag, minlen, maxlen); + if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL)) + return NULL; + if (!**p && tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + } + else if (tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + else if (!*soap->href && minlen > 0) + { soap->error = SOAP_LENGTH; + return NULL; + } + else + *p = soap_strdup(soap, SOAP_STR_EOS); + if (*soap->href) + p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0) + return soap->error; + if (!**p && (soap->mode & SOAP_C_NILSTRING)) + return soap_element_null(soap, tag, id, type); + if (soap_element_begin_out(soap, tag, id, type) + || soap_wstring_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + { if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + } + if (soap->body) + { *p = soap_wstring_in(soap, 1, minlen, maxlen); + if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL)) + return NULL; + if (!**p && tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + } + else if (tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + else if (soap->null) + *p = NULL; + else + *p = soap_wstrdup(soap, (wchar_t*)SOAP_STR_EOS); + if (*soap->href) + p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +time_t +SOAP_FMAC2 +soap_timegm(struct tm *T) +{ +#if defined(HAVE_TIMEGM) + return timegm(T); +#else + time_t t, g, z; + struct tm tm; + t = mktime(T); + if (t == (time_t)-1) + return (time_t)-1; +#ifdef HAVE_GMTIME_R + gmtime_r(&t, &tm); +#else + tm = *gmtime(&t); +#endif + tm.tm_isdst = 0; + g = mktime(&tm); + if (g == (time_t)-1) + return (time_t)-1; + z = g - t; + return t - z; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_dateTime2s(struct soap *soap, time_t n) +{ struct tm T, *pT = &T; +#if defined(HAVE_GMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GMTIME) + if ((pT = gmtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GETTIMEOFDAY) + struct timezone tz; + memset((void*)&tz, 0, sizeof(tz)); +#if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60); + } +#else + if ((pT = localtime(&n))) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60); + } +#endif +#elif defined(HAVE_FTIME) + struct timeb t; + memset((void*)&t, 0, sizeof(t)); +#if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { +#ifdef __BORLANDC__ + ::ftime(&t); +#else + ftime(&t); +#endif + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60); + } +#else + if ((pT = localtime(&n))) + { +#ifdef __BORLANDC__ + ::ftime(&t); +#else + ftime(&t); +#endif + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60); + } +#endif +#elif defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#else + if ((pT = localtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#endif + else + strcpy(soap->tmpbuf, "1969-12-31T23:59:59Z"); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdateTime(struct soap *soap, const char *tag, int id, const time_t *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_dateTime2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2dateTime(struct soap *soap, const char *s, time_t *p) +{ if (s) + { char zone[32]; + struct tm T; + const char *t; + *zone = '\0'; + memset((void*)&T, 0, sizeof(T)); + if (strchr(s, '-')) + t = "%d-%d-%dT%d:%d:%d%31s"; + else if (strchr(s, ':')) + t = "%4d%2d%2dT%d:%d:%d%31s"; + else /* parse non-XSD-standard alternative ISO 8601 format */ + t = "%4d%2d%2dT%2d%2d%2d%31s"; + if (sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone) < 6) + return soap->error = SOAP_TYPE; + if (T.tm_year == 1) + T.tm_year = 70; + else + T.tm_year -= 1900; + T.tm_mon--; + if (*zone == '.') + { for (s = zone + 1; *s; s++) + if (*s < '0' || *s > '9') + break; + } + else + s = zone; + if (*s) + { +#ifndef WITH_NOZONE + if (*s == '+' || *s == '-') + { int h = 0, m = 0; + if (s[3] == ':') + { /* +hh:mm */ + sscanf(s, "%d:%d", &h, &m); + if (h < 0) + m = -m; + } + else /* +hhmm */ + { m = (int)soap_strtol(s, NULL, 10); + h = m / 100; + m = m % 100; + } + T.tm_min -= m; + T.tm_hour -= h; + /* put hour and min in range */ + T.tm_hour += T.tm_min / 60; + T.tm_min %= 60; + if (T.tm_min < 0) + { T.tm_min += 60; + T.tm_hour--; + } + T.tm_mday += T.tm_hour / 24; + T.tm_hour %= 24; + if (T.tm_hour < 0) + { T.tm_hour += 24; + T.tm_mday--; + } + /* note: day of the month may be out of range, timegm() handles it */ + } +#endif + *p = soap_timegm(&T); + } + else /* no UTC or timezone, so assume we got a localtime */ + { T.tm_isdst = -1; + *p = mktime(&T); + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +time_t * +SOAP_FMAC2 +soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":dateTime")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL); + if (*soap->href) + p = (time_t*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(time_t), 0, NULL); + else if (p) + { if (soap_s2dateTime(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outliteral(struct soap *soap, const char *tag, char *const*p, const char *type) +{ int i; + const char *t = NULL; + if (tag && *tag != '-') + { if (soap->local_namespaces && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + if (soap_element(soap, t, 0, type) + || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS) + || soap_element_start_end_out(soap, NULL)) + return soap->error; + } + else + { t = tag; + if (soap_element_begin_out(soap, t, 0, type)) + return soap->error; + } + } + if (p && *p) + { if (soap_send(soap, *p)) + return soap->error; + } + if (t) + return soap_element_end_out(soap, t); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_inliteral(struct soap *soap, const char *tag, char **p) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + { if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + } + if (soap->body || (tag && *tag == '-')) + { *p = soap_string_in(soap, 0, -1, -1); + if (!*p) + return NULL; + if (!**p && tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + } + else if (soap->null) + *p = NULL; + else + *p = soap_strdup(soap, SOAP_STR_EOS); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p, const char *type) +{ int i; + const char *t = NULL; + if (tag && *tag != '-') + { if (soap->local_namespaces && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + if (soap_element(soap, t, 0, type) + || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS) + || soap_element_start_end_out(soap, NULL)) + return soap->error; + } + else + { t = tag; + if (soap_element_begin_out(soap, t, 0, type)) + return soap->error; + } + if (soap_send(soap, soap->tmpbuf)) + return soap->error; + } + if (p) + { wchar_t c; + const wchar_t *s = *p; + while ((c = *s++)) + { if (soap_pututf8(soap, (unsigned long)c)) + return soap->error; + } + } + if (t) + return soap_element_end_out(soap, t); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + { if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + } + if (soap->body) + { *p = soap_wstring_in(soap, 0, -1, -1); + if (!*p) + return NULL; + if (!**p && tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + } + else if (tag && *tag == '-') + { soap->error = SOAP_NO_TAG; + return NULL; + } + else if (soap->null) + *p = NULL; + else + *p = soap_wstrdup(soap, (wchar_t*)SOAP_STR_EOS); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_value(struct soap *soap) +{ register size_t i; + register soap_wchar c = 0; + register char *s = soap->tmpbuf; + if (!soap->body) + return SOAP_STR_EOS; + do c = soap_get(soap); + while (soap_blank(c)); + for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++) + { if (c == SOAP_TT || c == SOAP_LT || (int)c == EOF) + break; + *s++ = (char)c; + c = soap_get(soap); + } + for (s--; i > 0; i--, s--) + { if (!soap_blank((soap_wchar)*s)) + break; + } + s[1] = '\0'; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf)); + if (c == SOAP_TT || c == SOAP_LT || (int)c == EOF) + soap_unget(soap, c); + else if (soap->mode & SOAP_XML_STRICT) + { soap->error = SOAP_LENGTH; + return NULL; + } +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->data = soap_strdup(soap, soap->tmpbuf); +#endif + return soap->tmpbuf; /* return non-null pointer */ +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEANER) || !defined(WITH_NOHTTP) +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getline(struct soap *soap, char *s, int len) +{ int i = len; + soap_wchar c = 0; + for (;;) + { while (--i > 0) + { c = soap_getchar(soap); + if (c == '\r' || c == '\n') + break; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (c != '\n') + c = soap_getchar(soap); /* got \r or something else, now get \n */ + if (c == '\n') + { *s = '\0'; + if (i+1 == len) /* empty line: end of HTTP/MIME header */ + break; + c = soap_get0(soap); + if (c != ' ' && c != '\t') /* HTTP line continuation? */ + break; + } + else if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (i < 0) + return soap->error = SOAP_HDR; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static size_t +soap_count_attachments(struct soap *soap) +{ +#ifndef WITH_LEANER + register struct soap_multipart *content; + register size_t count = soap->count; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count)); + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n")); + for (content = soap->dime.first; content; content = content->next) + { count += 12 + ((content->size+3)&(~3)); + if (content->id) + count += ((strlen(content->id)+3)&(~3)); + if (content->type) + count += ((strlen(content->type)+3)&(~3)); + if (content->options) + count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment content is %lu bytes\n", (unsigned long)content->size)); + } + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary) + { register size_t n = strlen(soap->mime.boundary); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + { register const char *s; + /* count \r\n--boundary\r\n */ + count += 6 + n; + /* count Content-Type: ...\r\n */ + if (content->type) + count += 16 + strlen(content->type); + /* count Content-Transfer-Encoding: ...\r\n */ + s = soap_code_str(mime_codes, content->encoding); + if (s) + count += 29 + strlen(s); + /* count Content-ID: ...\r\n */ + if (content->id) + count += 14 + strlen(content->id); + /* count Content-Location: ...\r\n */ + if (content->location) + count += 20 + strlen(content->location); + /* count Content-Description: ...\r\n */ + if (content->description) + count += 23 + strlen(content->description); + /* count \r\n...content */ + count += 2 + content->size; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment content is %lu bytes\n", (unsigned long)content->size)); + } + /* count \r\n--boundary-- */ + count += 6 + n; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New count is %lu bytes\n", (unsigned long)count)); + return count; +#else + return soap->count; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_putdimefield(struct soap *soap, const char *s, size_t n) +{ if (soap_send_raw(soap, s, n)) + return soap->error; + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)n&3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_dime_option(struct soap *soap, unsigned short optype, const char *option) +{ size_t n; + char *s = NULL; + if (option) + { n = strlen(option); + s = (char*)soap_malloc(soap, n + 5); + if (s) + { s[0] = (char)(optype >> 8); + s[1] = (char)(optype & 0xFF); + s[2] = (char)(n >> 8); + s[3] = (char)(n & 0xFF); + strcpy(s + 4, option); + } + } + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdimehdr(struct soap *soap) +{ unsigned char tmp[12]; + size_t optlen = 0, idlen = 0, typelen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:SOAP_STR_EOS)); + if (soap->dime.options) + optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4; + if (soap->dime.id) + { idlen = strlen(soap->dime.id); + if (idlen > 0x0000FFFF) + idlen = 0x0000FFFF; + } + if (soap->dime.type) + { typelen = strlen(soap->dime.type); + if (typelen > 0x0000FFFF) + typelen = 0x0000FFFF; + } + tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7); + tmp[1] = soap->dime.flags & 0xF0; + tmp[2] = (char)(optlen >> 8); + tmp[3] = (char)(optlen & 0xFF); + tmp[4] = (char)(idlen >> 8); + tmp[5] = (char)(idlen & 0xFF); + tmp[6] = (char)(typelen >> 8); + tmp[7] = (char)(typelen & 0xFF); + tmp[8] = (char)(soap->dime.size >> 24); + tmp[9] = (char)((soap->dime.size >> 16) & 0xFF); + tmp[10] = (char)((soap->dime.size >> 8) & 0xFF); + tmp[11] = (char)(soap->dime.size & 0xFF); + if (soap_send_raw(soap, (char*)tmp, 12) + || soap_putdimefield(soap, soap->dime.options, optlen) + || soap_putdimefield(soap, soap->dime.id, idlen) + || soap_putdimefield(soap, soap->dime.type, typelen)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_DIME)) + return SOAP_OK; + for (content = soap->dime.first; content; content = content->next) + { void *handle; + soap->dime.size = content->size; + soap->dime.id = content->id; + soap->dime.type = content->type; + soap->dime.options = content->options; + soap->dime.flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA; + if (soap->fdimereadopen && ((handle = soap->fdimereadopen(soap, (void*)content->ptr, content->id, content->type, content->options)) || soap->error)) + { size_t size = content->size; + if (!handle) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadopen failed\n")); + return soap->error; + } + if (!size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE)) + { size_t chunksize = sizeof(soap->tmpbuf); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n")); + do + { size = soap->fdimeread(soap, handle, soap->tmpbuf, chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size)); + if (size < chunksize) + { soap->dime.flags &= ~SOAP_DIME_CF; + if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + } + else + soap->dime.flags |= SOAP_DIME_CF; + soap->dime.size = size; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, soap->tmpbuf, size)) + break; + if (soap->dime.id) + { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA); + soap->dime.id = NULL; + soap->dime.type = NULL; + soap->dime.options = NULL; + } + } while (size >= chunksize); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap)) + return soap->error; + do + { size_t bufsize; + if (size < sizeof(soap->tmpbuf)) + bufsize = size; + else + bufsize = sizeof(soap->tmpbuf); + if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size)); + soap->error = SOAP_EOF; + break; + } + if (soap_send_raw(soap, soap->tmpbuf, bufsize)) + break; + size -= bufsize; + } while (size); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + if (soap->fdimereadclose) + soap->fdimereadclose(soap, handle); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, (char*)content->ptr, content->size)) + return soap->error; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static char * +soap_getdimefield(struct soap *soap, size_t n) +{ register soap_wchar c; + register size_t i; + register char *s; + register char *p = NULL; + if (n) + { p = (char*)soap_malloc(soap, n + 1); + if (p) + { s = p; + for (i = n; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + *s++ = (char)c; + } + *s = '\0'; + if ((soap->error = soap_move(soap, -(long)n&3))) + return NULL; + } + else + soap->error = SOAP_EOM; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdimehdr(struct soap *soap) +{ register soap_wchar c; + register char *s; + register int i; + unsigned char tmp[12]; + size_t optlen, idlen, typelen; + if (!(soap->mode & SOAP_ENC_DIME)) + return soap->error = SOAP_DIME_END; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n")); + if (soap->dime.buflen || soap->dime.chunksize) + { if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap)))) + return soap->error = SOAP_EOF; + soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n")); + return SOAP_OK; + } + s = (char*)tmp; + for (i = 12; i > 0; i--) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION) + return soap->error = SOAP_DIME_MISMATCH; + soap->dime.flags = (tmp[0] & 0x7) | (tmp[1] & 0xF0); + optlen = (tmp[2] << 8) | tmp[3]; + idlen = (tmp[4] << 8) | tmp[5]; + typelen = (tmp[6] << 8) | tmp[7]; + soap->dime.size = (tmp[8] << 24) | (tmp[9] << 16) | (tmp[10] << 8) | tmp[11]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME size=%lu flags=0x%X\n", (unsigned long)soap->dime.size, soap->dime.flags)); + if (!(soap->dime.options = soap_getdimefield(soap, optlen)) && soap->error) + return soap->error; + if (!(soap->dime.id = soap_getdimefield(soap, idlen)) && soap->error) + return soap->error; + if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:SOAP_STR_EOS, soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:SOAP_STR_EOS)); + if (soap->dime.flags & SOAP_DIME_ME) + soap->mode &= ~SOAP_ENC_DIME; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdime(struct soap *soap) +{ while (soap->dime.flags & SOAP_DIME_CF) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap_move(soap, (long)soap->dime.size)) + return soap->error = SOAP_EOF; + } + if (soap_move(soap, (long)(((soap->dime.size+3)&(~3))-soap_tell(soap)))) + return soap->error = SOAP_EOF; + for (;;) + { register struct soap_multipart *content; + if (soap_getdimehdr(soap)) + break; + if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error)) + { const char *id, *type, *options; + size_t size, n; + if (!soap->dime.ptr) + return soap->error; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + for (;;) + { size = soap->dime.size; + for (;;) + { n = soap->buflen - soap->bufidx; + if (size < n) + n = size; + if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n))) + break; + size -= n; + if (!size) + { soap->bufidx += n; + break; + } + if (soap_recv(soap)) + { soap->error = SOAP_EOF; + goto end; + } + } + if (soap_move(soap, -(long)soap->dime.size&3)) + { soap->error = SOAP_EOF; + break; + } + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + break; + } +end: + if (soap->fdimewriteclose) + soap->fdimewriteclose(soap, (void*)soap->dime.ptr); + soap->dime.size = 0; + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else if (soap->dime.flags & SOAP_DIME_CF) + { const char *id, *type, *options; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + if (soap_new_block(soap) == NULL) + return SOAP_EOM; + for (;;) + { register soap_wchar c; + register size_t i; + register char *s; + s = (char*)soap_push_block(soap, NULL, soap->dime.size); + if (!s) + return soap->error = SOAP_EOM; + for (i = soap->dime.size; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (soap_move(soap, -(long)soap->dime.size&3)) + return soap->error = SOAP_EOF; + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + return soap->error; + } + soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */ + if (!(soap->dime.ptr = soap_save_block(soap, NULL, NULL, 0))) + return soap->error; + soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */ + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else + soap->dime.ptr = soap_getdimefield(soap, soap->dime.size); + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size); + if (!content) + return soap->error = SOAP_EOM; + content->id = soap->dime.id; + content->type = soap->dime.type; + content->options = soap->dime.options; + if (soap->error) + return soap->error; + soap_resolve_attachment(soap, content); + } + if (soap->error != SOAP_DIME_END) + return soap->error; + return soap->error = SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmimehdr(struct soap *soap) +{ struct soap_multipart *content; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + while (!*soap->msgbuf); + if (soap->msgbuf[0] == '-' && soap->msgbuf[1] == '-') + { char *s = soap->msgbuf + strlen(soap->msgbuf) - 1; + /* remove white space */ + while (soap_blank((soap_wchar)*s)) + s--; + s[1] = '\0'; + if (soap->mime.boundary) + { if (strcmp(soap->msgbuf + 2, soap->mime.boundary)) + return soap->error = SOAP_MIME_ERROR; + } + else + soap->mime.boundary = soap_strdup(soap, soap->msgbuf + 2); + if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + if (soap_set_mime_attachment(soap, NULL, 0, SOAP_MIME_NONE, NULL, NULL, NULL, NULL)) + return soap->error = SOAP_EOM; + content = soap->mime.last; + for (;;) + { register char *key = soap->msgbuf; + register char *val; + if (!*key) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key)); + val = strchr(soap->msgbuf, ':'); + if (val) + { *val = '\0'; + do val++; + while (*val && *val <= 32); + if (!soap_tag_cmp(key, "Content-ID")) + content->id = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Location")) + content->location = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Disposition")) + content->id = soap_strdup(soap, soap_get_header_attribute(soap, val, "name")); + else if (!soap_tag_cmp(key, "Content-Type")) + content->type = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Description")) + content->description = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Transfer-Encoding")) + content->encoding = (enum soap_mime_encoding)soap_code_int(mime_codes, val, (long)SOAP_MIME_NONE); + } + if (soap_getline(soap, key, sizeof(soap->msgbuf))) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmime(struct soap *soap) +{ while (soap_get_mime_attachment(soap, NULL)) + ; + return soap->error; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_post_check_mime_attachments(struct soap *soap) +{ soap->imode |= SOAP_MIME_POSTCHECK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_check_mime_attachments(struct soap *soap) +{ if (soap->mode & SOAP_MIME_POSTCHECK) + return soap_get_mime_attachment(soap, NULL) != NULL; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_multipart * +SOAP_FMAC2 +soap_get_mime_attachment(struct soap *soap, void *handle) +{ register soap_wchar c = 0; + register size_t i, m = 0; + register char *s, *t = NULL; + register struct soap_multipart *content; + register short flag = 0; + if (!(soap->mode & SOAP_ENC_MIME)) + return NULL; + content = soap->mime.last; + if (!content) + { if (soap_getmimehdr(soap)) + return NULL; + content = soap->mime.last; + } + else if (content != soap->mime.first) + { if (soap->fmimewriteopen && ((content->ptr = (char*)soap->fmimewriteopen(soap, (void*)handle, content->id, content->type, content->description, content->encoding)) || soap->error)) + { if (!content->ptr) + return NULL; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:SOAP_STR_EOS, content->type?content->type:SOAP_STR_EOS)); + if (!content->ptr && soap_new_block(soap) == NULL) + { soap->error = SOAP_EOM; + return NULL; + } + for (;;) + { if (content->ptr) + s = soap->tmpbuf; + else if (!(s = (char*)soap_push_block(soap, NULL, sizeof(soap->tmpbuf)))) + { soap->error = SOAP_EOM; + return NULL; + } + for (i = 0; i < sizeof(soap->tmpbuf); i++) + { if (m > 0) + { *s++ = *t++; + m--; + } + else + { if (!flag) + { c = soap_get1(soap); + if ((int)c == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + } + if (flag || c == '\r') + { t = soap->msgbuf; + memset(t, 0, sizeof(soap->msgbuf)); + strcpy(t, "\n--"); + if (soap->mime.boundary) + strncat(t, soap->mime.boundary, sizeof(soap->msgbuf)-4); + do c = soap_getchar(soap); + while (c == *t++); + if ((int)c == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + if (!*--t) + goto end; + *t = (char)c; + flag = (c == '\r'); + m = t - soap->msgbuf + 1 - flag; + t = soap->msgbuf; + c = '\r'; + } + *s++ = (char)c; + } + } + if (content->ptr && soap->fmimewrite) + { if ((soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i))) + break; + } + } +end: + *s = '\0'; /* force 0-terminated */ + if (content->ptr) + { if (!soap->error && soap->fmimewrite) + soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i); + if (soap->fmimewriteclose) + soap->fmimewriteclose(soap, (void*)content->ptr); + if (soap->error) + return NULL; + } + else + { content->size = soap_size_block(soap, NULL, i+1)-1; + content->ptr = soap_save_block(soap, NULL, NULL, 0); + } + soap_resolve_attachment(soap, content); + if (c == '-' && soap_getchar(soap) == '-') + { soap->mode &= ~SOAP_ENC_MIME; + if ((soap->mode & SOAP_MIME_POSTCHECK) && soap_end_recv(soap)) + { if (soap->keep_alive < 0) + soap->keep_alive = 0; + soap_closesock(soap); + return NULL; + } + } + else + { while (c != '\r' && (int)c != EOF && soap_blank(c)) + c = soap_getchar(soap); + if (c != '\r' || soap_getchar(soap) != '\n') + { soap->error = SOAP_MIME_ERROR; + return NULL; + } + if (soap_getmimehdr(soap)) + return NULL; + } + return content; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_cid(struct soap *soap, const char *s, const char *t) +{ register size_t n; + if (!s) + return 1; + if (!strcmp(s, t)) + return 0; + if (!strncmp(s, "cid:", 4)) + s += 4; + n = strlen(t); + if (*t == '<') + { t++; + n -= 2; + } + if (!strncmp(s, t, n) && !s[n]) + return 0; + soap_decode(soap->tmpbuf, sizeof(soap->tmpbuf), s, SOAP_STR_EOS); + if (!strncmp(soap->tmpbuf, t, n) && !soap->tmpbuf[n]) + return 0; + return 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_resolve_attachment(struct soap *soap, struct soap_multipart *content) +{ if (content->id) + { register struct soap_xlist **xp = &soap->xlist; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id)); + while (*xp) + { register struct soap_xlist *xq = *xp; + if (!soap_match_cid(soap, xq->id, content->id)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id)); + *xp = xq->next; + *xq->ptr = (unsigned char*)content->ptr; + *xq->size = (int)content->size; + *xq->type = (char*)content->type; + if (content->options) + *xq->options = (char*)content->options; + else + *xq->options = (char*)content->description; + SOAP_FREE(soap, xq); + } + else + xp = &(*xp)->next; + } + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmimehdr(struct soap *soap, struct soap_multipart *content) +{ const char *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:SOAP_STR_EOS)); + if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n")) + return soap->error; + if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n")) + return soap->error; + s = soap_code_str(mime_codes, content->encoding); + if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n")) + return soap->error; + if (content->id && soap_send3(soap, "Content-ID: ", content->id, "\r\n")) + return soap->error; + if (content->location && soap_send3(soap, "Content-Location: ", content->location, "\r\n")) + return soap->error; + if (content->description && soap_send3(soap, "Content-Description: ", content->description, "\r\n")) + return soap->error; + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_MIME) || !soap->mime.boundary) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + { void *handle; + if (soap->fmimereadopen && ((handle = soap->fmimereadopen(soap, (void*)content->ptr, content->id, content->type, content->description)) || soap->error)) + { size_t size = content->size; + if (!handle) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimereadopen failed\n")); + return soap->error; + } + if (soap_putmimehdr(soap, content)) + return soap->error; + if (!size) + { if ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming MIME\n")); + do + { size = soap->fmimeread(soap, handle, soap->tmpbuf, sizeof(soap->tmpbuf)); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread returned %lu bytes\n", (unsigned long)size)); + if (soap_send_raw(soap, soap->tmpbuf, size)) + break; + } while (size); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error: cannot chunk streaming MIME (no HTTP chunking)\n")); + } + } + else + { do + { size_t bufsize; + if (size < sizeof(soap->tmpbuf)) + bufsize = size; + else + bufsize = sizeof(soap->tmpbuf); + if (!(bufsize = soap->fmimeread(soap, handle, soap->tmpbuf, bufsize))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size)); + soap->error = SOAP_EOF; + break; + } + if (soap_send_raw(soap, soap->tmpbuf, bufsize)) + break; + size -= bufsize; + } while (size); + } + if (soap->fmimereadclose) + soap->fmimereadclose(soap, handle); + } + else + { if (soap_putmimehdr(soap, content) + || soap_send_raw(soap, content->ptr, content->size)) + return soap->error; + } + } + return soap_send3(soap, "\r\n--", soap->mime.boundary, "--"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_dime(struct soap *soap) +{ soap->omode |= SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_mime(struct soap *soap, const char *boundary, const char *start) +{ soap->omode |= SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = soap_strdup(soap, boundary); + soap->mime.start = soap_strdup(soap, start); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_dime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_mime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static struct soap_multipart* +soap_new_multipart(struct soap *soap, struct soap_multipart **first, struct soap_multipart **last, char *ptr, size_t size) +{ struct soap_multipart *content; + content = (struct soap_multipart*)soap_malloc(soap, sizeof(struct soap_multipart)); + if (content) + { content->next = NULL; + content->ptr = ptr; + content->size = size; + content->id = NULL; + content->type = NULL; + content->options = NULL; + content->encoding = SOAP_MIME_NONE; + content->location = NULL; + content->description = NULL; + if (!*first) + *first = content; + if (*last) + (*last)->next = content; + *last = content; + } + return content; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->options = soap_dime_option(soap, optype, option); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->encoding = encoding; + content->location = soap_strdup(soap, location); + content->description = soap_strdup(soap, description); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_multipart* +SOAP_FMAC2 +soap_next_multipart(struct soap_multipart *content) +{ if (content) + return content->next; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_select_mime_boundary(struct soap *soap) +{ while (!soap->mime.boundary || soap_valid_mime_boundary(soap)) + { register char *s = soap->mime.boundary; + register size_t n = 0; + if (s) + n = strlen(s); + if (n < 16) + { n = 64; + s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1); + if (!s) + return; + } + strcpy(s, "=="); + s += 2; + n -= 4; + while (n) + { *s++ = soap_base64o[soap_random & 0x3F]; + n--; + } + strcpy(s, "=="); + } + if (!soap->mime.start) + soap->mime.start = ""; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_valid_mime_boundary(struct soap *soap) +{ register struct soap_multipart *content; + register size_t k; + if (soap->fmimeread) + return SOAP_OK; + k = strlen(soap->mime.boundary); + for (content = soap->mime.first; content; content = content->next) + { if (content->ptr && content->size >= k) + { register const char *p = (const char*)content->ptr; + register size_t i; + for (i = 0; i < content->size - k; i++, p++) + { if (!strncmp(p, soap->mime.boundary, k)) + return SOAP_ERR; + } + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_GZIP +#ifndef PALM_1 +static int +soap_getgziphdr(struct soap *soap) +{ int i; + soap_wchar c = 0, f = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n")); + for (i = 0; i < 9; i++) + { if ((int)(c = soap_get1(soap) == EOF)) + return soap->error = SOAP_EOF; + if (i == 1 && c == 8) + soap->z_dict = 0; + if (i == 2) + f = c; + } + if (f & 0x04) /* FEXTRA */ + { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--) + { if ((int)soap_get1(soap) == EOF) + return soap->error = SOAP_EOF; + } + } + if (f & 0x08) /* skip FNAME */ + { do + c = soap_get1(soap); + while (c && (int)c != EOF); + } + if ((int)c != EOF && (f & 0x10)) /* skip FCOMMENT */ + { do + c = soap_get1(soap); + while (c && (int)c != EOF); + } + if ((int)c != EOF && (f & 0x02)) /* skip FHCRC (CRC32 is used) */ + { if ((int)(c = soap_get1(soap)) != EOF) + c = soap_get1(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_recv(struct soap *soap) +{ soap_wchar c; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for input\n")); + soap->error = SOAP_OK; + soap_free_temp(soap); + soap_set_local_namespaces(soap); + soap->version = 0; /* don't assume we're parsing SOAP content by default */ +#ifndef WITH_NOIDREF + soap_free_iht(soap); +#endif + if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK) + soap->omode |= SOAP_IO_CHUNK; + soap->imode &= ~(SOAP_IO | SOAP_ENC_MIME); + soap->mode = soap->imode; + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + soap->ahead = 0; + soap->peeked = 0; + soap->level = 0; + soap->part = SOAP_BEGIN; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + *soap->endpoint = '\0'; + soap->action = NULL; + soap->header = NULL; + soap->fault = NULL; + soap->status = 0; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.chunksize = 0; + soap->dime.buflen = 0; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +#endif +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) +#ifdef __BORLANDC__ + setmode(soap->recvfd, _O_BINARY); +#else + _setmode(soap->recvfd, _O_BINARY); +#endif +#endif +#endif +#endif +#ifdef WITH_ZLIB + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream->next_in = Z_NULL; + soap->d_stream->avail_in = 0; + soap->d_stream->next_out = (Byte*)soap->buf; + soap->d_stream->avail_out = SOAP_BUFLEN; + soap->z_ratio_in = 1.0; +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + ERR_clear_error(); +#endif +#ifndef WITH_LEANER + if (soap->fprepareinitrecv && (soap->error = soap->fprepareinitrecv(soap))) + return soap->error; +#endif + c = soap_getchar(soap); +#ifdef WITH_GZIP + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + if (soap->z_dict) + { if (inflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + } + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->mode |= SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_GZIP; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + if (!soap->z_buf) + soap->z_buf = (char*)SOAP_MALLOC(soap, SOAP_BUFLEN); + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + /* should not chunk over plain transport, so why bother to check? */ + /* if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) */ + /* soap->z_buflen = soap->bufidx; */ + /* else */ + soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream->avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + c = ' '; + } +#endif + while (soap_blank(c)) + c = soap_getchar(soap); +#ifndef WITH_LEANER + if (c == '-' && soap_get0(soap) == '-') + soap->mode |= SOAP_ENC_MIME; + else if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20) + soap->mode |= SOAP_ENC_DIME; + else +#endif + { /* skip BOM */ + if (c == 0xEF && (c = soap_getchar(soap)) == 0xBB && (c = soap_getchar(soap)) == 0xBF) + c = soap_getchar(soap); + /* skip space */ + while (soap_blank(c)) + c = soap_getchar(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifndef WITH_NOHTTP + /* if not XML or MIME/DIME/ZLIB, assume HTTP header */ + if (c != '<' && !(soap->mode & (SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_ZLIB))) + { soap_mode m = soap->imode; + soap->mode &= ~SOAP_IO; + soap->error = soap->fparse(soap); + if (soap->error && soap->error < SOAP_STOP) + { soap->keep_alive = 0; /* force close later */ + return soap->error; + } + if (soap->error == SOAP_STOP) + return soap->error; + soap->mode = soap->imode; /* if imode is changed, effectuate */ + soap->imode = m; /* restore imode */ +#ifdef WITH_ZLIB + soap->mode &= ~SOAP_ENC_ZLIB; +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { soap->chunkbuflen = soap->buflen; + soap->buflen = soap->bufidx; + soap->chunksize = 0; + } + /* Note: fparse should not use soap_unget to push back last char */ + if (soap_get0(soap) == (int)EOF) + { if (soap->status == 200) + return soap->error = SOAP_NO_DATA; /* HTTP OK: always expect data */ + return soap->error = soap->status; + } +#ifdef WITH_ZLIB + if (soap->zlib_in != SOAP_ZLIB_NONE) + { +#ifdef WITH_GZIP + if (soap->zlib_in != SOAP_ZLIB_DEFLATE) + { c = soap_get1(soap); + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + } + else + { soap_revget1(soap); + if (inflateInit(soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_in = SOAP_ZLIB_DEFLATE; + } + } + else +#endif + if (inflateInit(soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + if (soap->z_dict) + { if (inflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + } + soap->zlib_state = SOAP_ZLIB_INFLATE; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n")); + soap->mode |= SOAP_ENC_ZLIB; + if (!soap->z_buf) + soap->z_buf = (char*)SOAP_MALLOC(soap, SOAP_BUFLEN); + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream->avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + } +#endif +#ifndef WITH_LEANER + if (soap->fpreparerecv && (soap->mode & SOAP_IO) != SOAP_IO_CHUNK && soap->buflen > soap->bufidx) + { int r; + if ((r = soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx))) + return soap->error = r; + } +#endif + if (soap->error) + { if (soap->error == SOAP_FORM && soap->fform) + { soap->error = soap->fform(soap); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + } + return soap->error; + } + } +#endif +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_MIME) + { do /* skip preamble */ + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + } while (c != '-' || soap_get0(soap) != '-'); + soap_unget(soap, c); + if (soap_getmimehdr(soap)) + return soap->error; + if (soap->mime.start) + { do + { if (!soap->mime.last->id) + break; + if (!soap_match_cid(soap, soap->mime.start, soap->mime.last->id)) + break; + } while (soap_get_mime_attachment(soap, NULL)); + } + if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + } + if (soap->mode & SOAP_ENC_DIME) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked DIME SOAP message\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + soap->count = soap->buflen - soap->bufidx; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_out(struct soap *soap) +{ +#ifndef WITH_LEANER + size_t n = 0; + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start && strlen(soap->mime.boundary) + strlen(soap->mime.start) < sizeof(soap->tmpbuf) - 80 ) + { const char *s; + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + s = "application/dime"; + else if (soap->version == 2) + { if (soap->mode & SOAP_ENC_MTOM) + s = "application/xop+xml; charset=utf-8; type=\"application/soap+xml\""; + else + s = "application/soap+xml; charset=utf-8"; + } + else if (soap->mode & SOAP_ENC_MTOM) + s = "application/xop+xml; charset=utf-8; type=\"text/xml\""; + else + s = "text/xml; charset=utf-8"; + sprintf(soap->tmpbuf, "--%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\nContent-ID: %s\r\n\r\n", soap->mime.boundary, s, soap->mime.start); + n = strlen(soap->tmpbuf); + if (soap_send_raw(soap, soap->tmpbuf, n)) + return soap->error; + } + if (soap->mode & SOAP_IO_LENGTH) + soap->dime.size = soap->count; /* DIME in MIME correction */ + if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME)) + { if (soap_putdimehdr(soap)) + return soap->error; + } +#endif + soap->part = SOAP_IN_ENVELOPE; + return soap_element_begin_out(soap, "SOAP-ENV:Envelope", 0, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope") || ((soap->mode & SOAP_XML_INDENT) && soap_send_raw(soap, "\r\n", 2))) + return soap->error; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + { soap->dime.size = soap->count - soap->dime.size; /* DIME in MIME correction */ + sprintf(soap->id, soap->dime_id_format, 0); + soap->dime.id = soap->id; + if (soap->local_namespaces) + { if (soap->local_namespaces[0].out) + soap->dime.type = (char*)soap->local_namespaces[0].out; + else + soap->dime.type = (char*)soap->local_namespaces[0].ns; + } + soap->dime.options = NULL; + soap->dime.flags = SOAP_DIME_MB | SOAP_DIME_ABSURI; + if (!soap->dime.first) + soap->dime.flags |= SOAP_DIME_ME; + soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + (soap->dime.type ? ((strlen(soap->dime.type)+3)&(~3)) : 0); + } + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); +#endif + soap->part = SOAP_END_ENVELOPE; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_get_http_body(struct soap *soap) +{ +#ifndef WITH_LEAN + register size_t l = 0, n = 0; + register char *s; + /* get HTML body of HTTP error content */ + if (!(soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) != SOAP_IO_CHUNK) + { n = soap->length; + if (!n) + return NULL; + } +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap) == NULL) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t i, k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t i, k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, NULL, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { register soap_wchar c = soap_getchar(soap); + if ((int)c == EOF) + goto end; + *s++ = (char)(c & 0xFF); + l++; + if (n > 0 && l >= n) + goto end; + } + } +end: + *s = '\0'; +#ifdef WITH_FAST + s = soap_strdup(soap, soap->labbuf); +#else + soap_size_block(soap, NULL, i+1); + s = soap_save_block(soap, NULL, 0); +#endif + return s; +#else + return NULL; +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_in(struct soap *soap) +{ register struct Namespace *p; + soap->part = SOAP_IN_ENVELOPE; + if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0, NULL)) + { if (soap->error == SOAP_TAG_MISMATCH + && !soap_element_begin_in(soap, "Envelope", 0, NULL)) + soap->error = SOAP_VERSIONMISMATCH; + else if (soap->status) + soap->error = soap->status; + return soap->error; + } + p = soap->local_namespaces; + if (p) + { const char *ns = p[0].out; + if (!ns) + ns = p[0].ns; + if (!strcmp(ns, soap_env1)) + { soap->version = 1; /* make sure we use SOAP 1.1 */ + if (p[1].out) + SOAP_FREE(soap, p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc1)))) + strcpy(p[1].out, soap_enc1); + } + else if (!strcmp(ns, soap_env2)) + { soap->version = 2; /* make sure we use SOAP 1.2 */ + if (p[1].out) + SOAP_FREE(soap, p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc2)))) + strcpy(p[1].out, soap_enc2); + } + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_in(struct soap *soap) +{ soap->part = SOAP_END_ENVELOPE; + return soap_element_end_in(soap, "SOAP-ENV:Envelope"); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_out(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap->version == 1) + soap->encoding = 1; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_SEC) && soap_set_attr(soap, "wsu:Id", "Body", 1)) + return soap->error; +#endif + if (soap_element(soap, "SOAP-ENV:Body", 0, NULL)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Body")) + return soap->error; + soap->part = SOAP_END_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_in(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap_element_begin_in(soap, "SOAP-ENV:Body", 0, NULL)) + return soap->error; + if (!soap->body) + soap->part = SOAP_NO_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_in(struct soap *soap) +{ if (soap->part == SOAP_NO_BODY) + return soap->error = SOAP_OK; + soap->part = SOAP_END_BODY; + return soap_element_end_in(soap, "SOAP-ENV:Body"); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_header(struct soap *soap) +{ if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH) + soap->error = SOAP_OK; + if (soap->error == SOAP_OK && soap->fheader) + soap->error = soap->fheader(soap); + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_endpoint(struct soap *soap, const char *endpoint) +{ register const char *s; + register size_t i, n; + soap->endpoint[0] = '\0'; + soap->host[0] = '\0'; + soap->path[0] = '/'; + soap->path[1] = '\0'; + soap->port = 80; + if (!endpoint || !*endpoint) + return; +#ifdef WITH_OPENSSL + if (!soap_tag_cmp(endpoint, "https:*")) + soap->port = 443; +#endif + strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + s = strchr(endpoint, ':'); + if (s && s[1] == '/' && s[2] == '/') + s += 3; + else + s = endpoint; + n = strlen(s); + if (n >= sizeof(soap->host)) + n = sizeof(soap->host) - 1; +#ifdef WITH_IPV6 + if (s[0] == '[') + { s++; + for (i = 0; i < n; i++) + { if (s[i] == ']') + { s++; + --n; + break; + } + soap->host[i] = s[i]; + } + } + else + { for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } + } +#else + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } +#endif + soap->host[i] = '\0'; + if (s[i] == ':') + { soap->port = (int)soap_strtol(s + i + 1, NULL, 10); + for (i++; i < n; i++) + if (s[i] == '/') + break; + } + if (i < n && s[i]) + { strncpy(soap->path, s + i, sizeof(soap->path)); + soap->path[sizeof(soap->path) - 1] = '\0'; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect(struct soap *soap, const char *endpoint, const char *action) +{ return soap_connect_command(soap, SOAP_POST, endpoint, action); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect_command(struct soap *soap, int http_command, const char *endpoints, const char *action) +{ char *endpoint; + const char *s; + if (endpoints && (s = strchr(endpoints, ' '))) + { endpoint = (char*)SOAP_MALLOC(soap, strlen(endpoints) + 1); + for (;;) + { strncpy(endpoint, endpoints, s - endpoints); + endpoint[s - endpoints] = '\0'; + if (soap_try_connect_command(soap, http_command, endpoint, action) != SOAP_TCP_ERROR) + break; + if (!*s) + break; + soap->error = SOAP_OK; + while (*s == ' ') + s++; + endpoints = s; + s = strchr(endpoints, ' '); + if (!s) + s = endpoints + strlen(endpoints); + } + SOAP_FREE(soap, endpoint); + } + else + soap_try_connect_command(soap, http_command, endpoints, action); + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +soap_try_connect_command(struct soap *soap, int http_command, const char *endpoint, const char *action) +{ char host[sizeof(soap->host)]; + int port; + size_t count; + soap->error = SOAP_OK; + strcpy(host, soap->host); /* save previous host name: if != then reconnect */ + port = soap->port; /* save previous port to compare */ + soap->status = http_command; + soap_set_endpoint(soap, endpoint); +#ifndef WITH_LEANER + if (soap->fconnect) + { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port))) + return soap->error; + } + else +#endif + if (soap->fopen && *soap->host) + { if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap)) + { soap->keep_alive = 0; /* to force close */ + soap->omode &= ~SOAP_IO_UDP; /* to force close */ + soap_closesock(soap); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port)); +#ifndef WITH_LEAN + if (!strncmp(endpoint, "soap.udp:", 9)) + soap->omode |= SOAP_IO_UDP; +#endif + soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port); + if (soap->error) + return soap->error; + soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0); + } + } + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; + if (http_command == SOAP_GET) + { soap->mode &= ~SOAP_IO; + soap->mode |= SOAP_IO_BUFFER; + } +#ifndef WITH_NOHTTP + soap->action = soap_strdup(soap, action); + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint) + { unsigned int k = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((k & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count))) + return soap->error; +#ifndef WITH_LEANER + if ((k & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = k; + } + if (http_command == SOAP_GET) + return soap_end_send(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n) +{ register int i; + register unsigned long m; + register char *p; + if (!t) + t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1); + if (!t) + return NULL; + p = t; + t[0] = '\0'; + if (!s) + return p; + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + t += 4; + } + t[0] = '\0'; + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + t[i] = '='; + t[4] = '\0'; + } + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n) +{ register int i, j, c; + register unsigned long m; + register const char *p; + if (!s || !*s) + { if (n) + *n = 0; + if (soap->error) + return NULL; + return SOAP_NON_NULL; + } + if (!t) + { l = (strlen(s) + 3) / 4 * 3; + t = (char*)soap_malloc(soap, l); + } + if (!t) + return NULL; + p = t; + if (n) + *n = 0; + for (;;) + { for (i = 0; i < SOAP_BLKLEN; i++) + { m = 0; + j = 0; + while (j < 4) + { c = *s++; + if (c == '=' || !c) + { i *= 3; + switch (j) + { case 2: + *t++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *t++ = (char)((m >> 10) & 0xFF); + *t++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n += i; + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { int b = soap_base64i[c]; + if (b >= 64) + { soap->error = SOAP_TYPE; + return NULL; + } + m = (m << 6) + b; + j++; + } + else if (!soap_blank(c + '+')) + { soap->error = SOAP_TYPE; + return NULL; + } + } + *t++ = (char)((m >> 16) & 0xFF); + *t++ = (char)((m >> 8) & 0xFF); + *t++ = (char)(m & 0xFF); + if (l < 3) + { if (n) + *n += i; + return p; + } + l -= 3; + } + if (n) + *n += 3 * SOAP_BLKLEN; + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n) +{ register char *p; + if (!t) + t = (char*)soap_malloc(soap, 2 * n + 1); + if (!t) + return NULL; + p = t; + t[0] = '\0'; + if (s) + { for (; n > 0; n--) + { register int m = *s++; + *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0')); + m &= 0x0F; + *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0')); + } + } + *t++ = '\0'; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n) +{ register const char *p; + if (!s || !*s) + { if (n) + *n = 0; + if (soap->error) + return NULL; + return SOAP_NON_NULL; + } + if (!t) + { l = strlen(s) / 2; + t = (char*)soap_malloc(soap, l); + } + if (!t) + return NULL; + p = t; + while (l) + { register int d1, d2; + d1 = *s++; + if (!d1) + break; + d2 = *s++; + if (!d2) + break; + *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + l--; + } + if (n) + *n = (int)(t - p); + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthttphdr(struct soap *soap, int status, size_t count) +{ if (soap->status != SOAP_GET) + { register const char *s = "text/xml; charset=utf-8"; + register int err = SOAP_OK; +#ifndef WITH_LEANER + register const char *r = NULL; +#endif + if ((status == SOAP_FILE || soap->status == SOAP_POST_FILE) && soap->http_content) + s = soap->http_content; + else if (status == SOAP_HTML) + s = "text/html; charset=utf-8"; + else if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)) + { if (soap->version == 2) + s = "application/soap+xml; charset=utf-8"; + } +#ifndef WITH_LEANER + if (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MTOM)) + { if (soap->mode & SOAP_ENC_MTOM) + { if (soap->version == 2) + r = "application/soap+xml"; + else + r = "text/xml"; + s = "application/xop+xml"; + } + else + s = "application/dime"; + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && strlen(soap->mime.boundary) + strlen(soap->mime.start ? soap->mime.start : SOAP_STR_EOS) < sizeof(soap->tmpbuf) - 80) + { register const char *t = strchr(s, ';'); + sprintf(soap->tmpbuf, "multipart/related; charset=utf-8; boundary=\"%s\"; type=\"", soap->mime.boundary); + if (t) + { strncat(soap->tmpbuf, s, t - s); + soap->tmpbuf[sizeof(soap->tmpbuf)-1] = '\0'; + } + else + strcat(soap->tmpbuf, s); + if (soap->mime.start) + { strcat(soap->tmpbuf, "\"; start=\""); + strcat(soap->tmpbuf, soap->mime.start); + } + strcat(soap->tmpbuf, "\""); + if (r) + { strcat(soap->tmpbuf, "; start-info=\""); + strcat(soap->tmpbuf, r); + strcat(soap->tmpbuf, "\""); + } + s = soap->tmpbuf; + } + else if (status == SOAP_OK && soap->action && strlen(soap->action) < sizeof(soap->tmpbuf) - 80) + { sprintf(soap->tmpbuf, "%s; action=\"%s\"", s, soap->action); + s = soap->tmpbuf; + } +#endif + if (s && (err = soap->fposthdr(soap, "Content-Type", s))) + return err; +#ifdef WITH_ZLIB + if ((soap->omode & SOAP_ENC_ZLIB)) + { +#ifdef WITH_GZIP + err = soap->fposthdr(soap, "Content-Encoding", soap->zlib_out == SOAP_ZLIB_DEFLATE ? "deflate" : "gzip"); +#else + err = soap->fposthdr(soap, "Content-Encoding", "deflate"); +#endif + if (err) + return err; + } +#endif +#ifndef WITH_LEANER + if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK) + err = soap->fposthdr(soap, "Transfer-Encoding", "chunked"); + else +#endif + if (s) + { sprintf(soap->tmpbuf, "%lu", (unsigned long)count); + err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf); + } + if (err) + return err; + } + return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static const char* +soap_set_validation_fault(struct soap *soap, const char *s, const char *t) +{ if (*soap->tag) + sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element '%s'", s, t?t:SOAP_STR_EOS, soap->tag); + else + sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS); + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_fault(struct soap *soap) +{ const char **c = soap_faultcode(soap); + const char **s = soap_faultstring(soap); + if (soap->fseterror) + soap->fseterror(soap, c, s); + if (!*c) + { if (soap->version == 2) + *c = "SOAP-ENV:Sender"; + else + *c = "SOAP-ENV:Client"; + } + if (*s) + return; + switch (soap->error) + { +#ifndef WITH_LEAN + case SOAP_CLI_FAULT: + *s = "Client fault"; + break; + case SOAP_SVR_FAULT: + *s = "Server fault"; + break; + case SOAP_TAG_MISMATCH: + *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL); + break; + case SOAP_TYPE: + *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type); + break; + case SOAP_SYNTAX_ERROR: + *s = "Well-formedness violation"; + break; + case SOAP_NO_TAG: + *s = "No XML root element"; + break; + case SOAP_MUSTUNDERSTAND: + *c = "SOAP-ENV:MustUnderstand"; + sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_VERSIONMISMATCH: + *c = "SOAP-ENV:VersionMismatch"; + *s = "Invalid SOAP message or SOAP version mismatch"; + break; + case SOAP_DATAENCODINGUNKNOWN: + *c = "SOAP-ENV:DataEncodingUnknown"; + *s = "Unsupported SOAP data encoding"; + break; + case SOAP_NAMESPACE: + *s = soap_set_validation_fault(soap, "namespace error", NULL); + break; + case SOAP_USER_ERROR: + *s = "User error"; + break; + case SOAP_FATAL_ERROR: + *s = "Fatal error"; + break; + case SOAP_NO_METHOD: + sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_NO_DATA: + *s = "Data required for operation"; + break; + case SOAP_GET_METHOD: + *s = "HTTP GET method not implemented"; + break; + case SOAP_PUT_METHOD: + *s = "HTTP PUT method not implemented"; + break; + case SOAP_HTTP_METHOD: + *s = "HTTP method not implemented"; + break; + case SOAP_EOM: + *s = "Out of memory"; + break; + case SOAP_MOE: + *s = "Memory overflow or memory corruption error"; + break; + case SOAP_HDR: + *s = "Header line too long"; + break; + case SOAP_IOB: + *s = "Array index out of bounds"; + break; + case SOAP_NULL: + *s = soap_set_validation_fault(soap, "nil not allowed", NULL); + break; + case SOAP_DUPLICATE_ID: + *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id); + if (soap->version == 2) + *soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID"; + break; + case SOAP_MISSING_ID: + *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id); + if (soap->version == 2) + *soap_faultsubcode(soap) = "SOAP-ENC:MissingID"; + break; + case SOAP_HREF: + *s = soap_set_validation_fault(soap, "incompatible object type ref/id pair ", soap->id); + break; + case SOAP_FAULT: + break; +#ifndef WITH_NOIO + case SOAP_UDP_ERROR: + *s = "Message too large for UDP packet"; + break; + case SOAP_TCP_ERROR: + *s = tcp_error(soap); + break; +#endif + case SOAP_HTTP_ERROR: + *s = "An HTTP processing error occurred"; + break; + case SOAP_SSL_ERROR: +#ifdef WITH_OPENSSL + *s = "SSL/TLS error"; +#else + *s = "OpenSSL not installed: recompile with -DWITH_OPENSSL"; +#endif + break; + case SOAP_PLUGIN_ERROR: + *s = "Plugin registry error"; + break; + case SOAP_DIME_ERROR: + *s = "DIME format error"; + break; + case SOAP_DIME_HREF: + *s = "DIME href to missing attachment"; + break; + case SOAP_DIME_MISMATCH: + *s = "DIME version/transmission error"; + break; + case SOAP_DIME_END: + *s = "End of DIME error"; + break; + case SOAP_MIME_ERROR: + *s = "MIME format error"; + break; + case SOAP_MIME_HREF: + *s = "MIME href to missing attachment"; + break; + case SOAP_MIME_END: + *s = "End of MIME error"; + break; + case SOAP_ZLIB_ERROR: +#ifdef WITH_ZLIB + sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS); + *s = soap->msgbuf; +#else + *s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP"; +#endif + break; + case SOAP_REQUIRED: + *s = soap_set_validation_fault(soap, "missing required attribute", NULL); + break; + case SOAP_PROHIBITED: + *s = soap_set_validation_fault(soap, "prohibited attribute present", NULL); + break; + case SOAP_OCCURS: + *s = soap_set_validation_fault(soap, "occurrence violation", NULL); + break; + case SOAP_LENGTH: + *s = soap_set_validation_fault(soap, "content range or length violation", NULL); + break; + case SOAP_FD_EXCEEDED: + *s = "Maximum number of open connections was reached (no define HAVE_POLL): increase FD_SETSIZE"; + break; + case SOAP_STOP: + *s = "Stopped: no response to be sent or received (informative)"; + break; +#endif + case SOAP_EOF: +#ifndef WITH_NOIO + strcpy(soap->msgbuf, soap_strerror(soap)); +#ifndef WITH_LEAN + if (strlen(soap->msgbuf) + 25 < sizeof(soap->msgbuf)) + { memmove(soap->msgbuf + 25, soap->msgbuf, strlen(soap->msgbuf) + 1); + memcpy(soap->msgbuf, "End of file or no input: ", 25); + } +#endif + *s = soap->msgbuf; + break; +#else + *s = "End of file or no input"; + break; +#endif + default: +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN + if (soap->error > 200 && soap->error < 600) + { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error)); + *s = soap->msgbuf; + } + else +#endif +#endif + { sprintf(soap->msgbuf, "Error %d", soap->error); + *s = soap->msgbuf; + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_fault(struct soap *soap) +{ register int status = soap->error; + if (status == SOAP_STOP) + return soap_closesock(soap); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error)); + soap->keep_alive = 0; /* to terminate connection */ + soap_set_fault(soap); + if (soap->error < 200 && soap->error != SOAP_FAULT) + soap->header = NULL; + if (status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) + { int r = 1; +#ifndef WITH_NOIO + if (soap->fpoll && soap->fpoll(soap)) + r = 0; +#ifndef WITH_LEAN + else if (soap_valid_socket(soap->socket)) + { r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_SND, 0); + if (r > 0) + { if (!(r & SOAP_TCP_SELECT_SND) + || ((r & SOAP_TCP_SELECT_RCV) + && recv(soap->socket, soap->tmpbuf, 1, MSG_PEEK) < 0)) + r = 0; + } + } +#endif +#endif + if (r > 0) + { soap->error = SOAP_OK; + soap_serializeheader(soap); + soap_serializefault(soap); + soap_begin_count(soap); + if (soap->mode & SOAP_IO_LENGTH) + { soap_envelope_begin_out(soap); + soap_putheader(soap); + soap_body_begin_out(soap); + soap_putfault(soap); + soap_body_end_out(soap); + soap_envelope_end_out(soap); + } + soap_end_count(soap); + if (soap_response(soap, status) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_putfault(soap) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap_closesock(soap); + soap_end_send(soap); + } + } + soap->error = status; + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_fault(struct soap *soap, int check) +{ register int status = soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Check if receiving SOAP Fault\n")); + if (!check) + { /* try getfault when no tag or tag mismatched at level 2, otherwise ret */ + if (soap->error != SOAP_NO_TAG + && (soap->error != SOAP_TAG_MISMATCH || soap->level != 2)) + return soap->error; + } + soap->error = SOAP_OK; + if (soap_getfault(soap)) + { /* check flag set: check if SOAP Fault is present, if not just return */ + if (check && soap->error == SOAP_TAG_MISMATCH && soap->level == 2) + return soap->error = SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Error: soap_get_soapfault() failed. Is this a SOAP message at all?\n")); + *soap_faultcode(soap) = (soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client"); + soap->error = status; + soap_set_fault(soap); + } + else + { register const char *s = *soap_faultcode(soap); + if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver")) + status = SOAP_SVR_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender")) + status = SOAP_CLI_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:MustUnderstand")) + status = SOAP_MUSTUNDERSTAND; + else if (!soap_match_tag(soap, s, "SOAP-ENV:VersionMismatch")) + status = SOAP_VERSIONMISMATCH; + else + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Received SOAP Fault code %s\n", s)); + status = SOAP_FAULT; + } + if (!soap_body_end_in(soap)) + soap_envelope_end_in(soap); + } + soap_end_recv(soap); + soap->error = status; + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_empty_response(struct soap *soap, int httpstatuscode) +{ register soap_mode m = soap->omode; + soap->count = 0; + if ((m & SOAP_IO) == SOAP_IO_CHUNK) + soap->omode = (m & ~SOAP_IO) | SOAP_IO_BUFFER; + if (soap_response(soap, httpstatuscode) || soap_end_send(soap)) + { soap->omode = m; + return soap_closesock(soap); + } + soap->omode = m; + return soap->error = SOAP_STOP; /* stops the server's response */ +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_empty_response(struct soap *soap) +{ if (!soap_begin_recv(soap)) + soap_end_recv(soap); + else if (soap->error == SOAP_NO_DATA || soap->error == 202) + soap->error = SOAP_OK; + return soap_closesock(soap); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +soap_strerror(struct soap *soap) +{ register int err = soap->errnum; + if (err) + { +#ifndef WIN32 +# ifdef HAVE_STRERROR_R + strerror_r(err, soap->msgbuf, sizeof(soap->msgbuf)); +# else + return strerror(err); +# endif +#else +#ifndef UNDER_CE + DWORD len; + *soap->msgbuf = '\0'; + len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)soap->msgbuf, (DWORD)sizeof(soap->msgbuf), NULL); +#else + DWORD i, len; + *soap->msgbuf = '\0'; + len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)soap->msgbuf, (DWORD)(sizeof(soap->msgbuf)/sizeof(TCHAR)), NULL); + for (i = 0; i <= len; i++) + { if (((TCHAR*)soap->msgbuf)[i] < 0x80) + soap->msgbuf[i] = (char)((TCHAR*)soap->msgbuf)[i]; + else + soap->msgbuf[i] = '?'; + } +#endif +#endif + } + else + { char *s = soap->msgbuf; +#ifndef WITH_LEAN + int rt = soap->recv_timeout, st = soap->send_timeout; + int ru = ' ', su = ' '; +#endif + strcpy(s, "Operation interrupted or timed out"); +#ifndef WITH_LEAN + if (rt < 0) + { rt = -rt; + ru = 'u'; + } + if (st < 0) + { st = -st; + su = 'u'; + } + if (rt) + sprintf(s + strlen(s), " (%d%cs receive delay)", rt, ru); + if (st) + sprintf(s + strlen(s), " (%d%cs send delay)", st, su); +#endif + } + return soap->msgbuf; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML, int soaperror) +{ *soap_faultcode(soap) = faultcode; + if (faultsubcodeQName) + *soap_faultsubcode(soap) = faultsubcodeQName; + *soap_faultstring(soap) = faultstring; + if (faultdetailXML && *faultdetailXML) + { register const char **s = soap_faultdetail(soap); + if (s) + *s = faultdetailXML; + } + return soap->error = soaperror; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetailXML, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", NULL, faultstring, faultdetailXML, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetailXML, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", NULL, faultstring, faultdetailXML, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML) +{ char *r = NULL, *s = NULL, *t = NULL; + if (faultsubcodeQName) + r = soap_strdup(soap, faultsubcodeQName); + if (faultstring) + s = soap_strdup(soap, faultstring); + if (faultdetailXML) + t = soap_strdup(soap, faultdetailXML); + return soap_set_error(soap, faultcode, r, s, t, SOAP_FAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetailXML) +{ return soap_sender_fault_subcode(soap, NULL, faultstring, faultdetailXML); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault_subcode(struct soap *soap, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultsubcodeQName, faultstring, faultdetailXML); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetailXML) +{ return soap_receiver_fault_subcode(soap, NULL, faultstring, faultdetailXML); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault_subcode(struct soap *soap, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultsubcodeQName, faultstring, faultdetailXML); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault(struct soap *soap, FILE *fd) +{ if (soap_check_state(soap)) + fprintf(fd, "Error: soap struct state not initialized\n"); + else if (soap->error) + { const char *c, *v = NULL, *s, **d; + d = soap_faultcode(soap); + if (!*d) + soap_set_fault(soap); + c = *d; + if (soap->version == 2) + v = *soap_faultsubcode(soap); + s = *soap_faultstring(soap); + d = soap_faultdetail(soap); + fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]"); + } +} +#endif +#endif + +/******************************************************************************/ +#ifdef __cplusplus +#ifndef WITH_LEAN +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_stream_fault(struct soap *soap, std::ostream& os) +{ if (soap_check_state(soap)) + os << "Error: soap struct state not initialized\n"; + else if (soap->error) + { const char *c, *v = NULL, *s, **d; + d = soap_faultcode(soap); + if (!*d) + soap_set_fault(soap); + c = *d; + if (soap->version == 2) + v = *soap_faultsubcode(soap); + s = *soap_faultstring(soap); + d = soap_faultdetail(soap); + os << (soap->version ? "SOAP 1." : "Error ") + << (soap->version ? (int)soap->version : soap->error) + << " fault: " << c + << "[" << (v ? v : "no subcode") << "]" + << std::endl + << "\"" << (s ? s : "[no reason]") << "\"" + << std::endl + << "Detail: " << (d && *d ? *d : "[no detail]") + << std::endl; + } +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_sprint_fault(struct soap *soap, char *buf, size_t len) +{ if (soap_check_state(soap)) + strncpy(buf, "Error: soap struct not initialized", len); + else if (soap->error) + { const char *c, *v = NULL, *s, **d; + d = soap_faultcode(soap); + if (!*d) + soap_set_fault(soap); + c = *d; + if (soap->version == 2) + v = *soap_faultsubcode(soap); + s = *soap_faultstring(soap); + d = soap_faultdetail(soap); +#ifdef HAVE_SNPRINTF +# ifdef WIN32 + _snprintf +# else + snprintf +# endif + (buf, len, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]"); +#else + if (len > 40 + (v ? strlen(v) : 0) + (s ? strlen(s) : 0) + (d && *d ? strlen(*d) : 0)) + sprintf(buf, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]"); + else if (len > 40) + sprintf(buf, "%s%d fault: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c); + else + buf[0] = '\0'; +#endif + } + return buf; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault_location(struct soap *soap, FILE *fd) +{ +#ifndef WITH_LEAN + int i, j, c1, c2; + if (soap->error && soap->error != SOAP_STOP && soap->bufidx <= soap->buflen && soap->buflen > 0 && soap->buflen <= SOAP_BUFLEN) + { i = (int)soap->bufidx - 1; + if (i <= 0) + i = 0; + c1 = soap->buf[i]; + soap->buf[i] = '\0'; + if ((int)soap->buflen >= i + 1024) + j = i + 1023; + else + j = (int)soap->buflen - 1; + c2 = soap->buf[j]; + soap->buf[j] = '\0'; + fprintf(fd, "%s%c\n\n", soap->buf, c1); + if (soap->bufidx < soap->buflen) + fprintf(fd, "%s\n", soap->buf + soap->bufidx); + soap->buf[i] = c1; + soap->buf[j] = c2; + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg) +{ register struct soap_plugin *p; + register int r; + if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin)))) + return soap->error = SOAP_EOM; + p->id = NULL; + p->data = NULL; + p->fcopy = NULL; + p->fdelete = NULL; + r = fcreate(soap, p, arg); + if (!r && p->fdelete) + { p->next = soap->plugins; + soap->plugins = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id)); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r)); + SOAP_FREE(soap, p); + return r; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static void * +fplugin(struct soap *soap, const char *id) +{ register struct soap_plugin *p; + for (p = soap->plugins; p; p = p->next) + if (p->id == id || !strcmp(p->id, id)) + return p->data; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void * +SOAP_FMAC2 +soap_lookup_plugin(struct soap *soap, const char *id) +{ return soap->fplugin(soap, id); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif + +/******************************************************************************\ + * + * C++ soap struct methods + * +\******************************************************************************/ + +#ifdef __cplusplus +soap::soap() +{ soap_init(this); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +soap::soap(soap_mode m) +{ soap_init1(this, m); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +soap::soap(soap_mode im, soap_mode om) +{ soap_init2(this, im, om); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +soap::soap(const struct soap& soap) +{ soap_copy_context(this, &soap); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +soap::~soap() +{ soap_destroy(this); + soap_end(this); + soap_done(this); +} +#endif + +/******************************************************************************/ diff --git a/ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.h b/ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.h new file mode 100644 index 000000000..779de5101 --- /dev/null +++ b/ext/CrashServer/external/gsoap-win32-2.8.0/stdsoap2.h @@ -0,0 +1,2472 @@ +/* + stdsoap2.h 2.8.0 + + gSOAP runtime engine + +gSOAP XML Web services tools +Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc., All Rights Reserved. +This part of the software is released under ONE of the following licenses: +GPL, or the gSOAP public license, or Genivia's license for commercial use. +-------------------------------------------------------------------------------- +Contributors: + +Wind River Systems, Inc., for the following additions + - vxWorks compatible +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(the "License"); you may not use this file except in compliance with the +License. You may obtain a copy of the License at +http://www.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org + +This program is released under the GPL with the additional exemption that +compiling, linking, and/or using OpenSSL is allowed. +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- +*/ + +#ifdef WITH_SOAPDEFS_H +# include "soapdefs.h" /* include user-defined stuff */ +#endif + +#ifndef _THREAD_SAFE +# define _THREAD_SAFE +#endif + +#ifndef OPENSERVER +# ifndef _REENTRANT +# define _REENTRANT +# endif +#endif + +#ifndef SOAP_FMAC1 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC1 +#endif + +#ifndef SOAP_FMAC2 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC2 +#endif + +#ifndef SOAP_FMAC3 /* (de)serializer declaration macro */ +# define SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC3S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC3S SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC4 /* (de)serializer declaration macro */ +# define SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC4S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC4S SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC5 /* stub/skeleton declaration macro */ +# define SOAP_FMAC5 +#endif + +#ifndef SOAP_FMAC6 /* stub/skeleton declaration macro */ +# define SOAP_FMAC6 +#endif + +#ifndef SOAP_CMAC /* class declaration macro */ +# define SOAP_CMAC +#endif + +#ifndef SOAP_NMAC /* namespace table declaration macro */ +# define SOAP_NMAC +#endif + +#ifndef SOAP_SOURCE_STAMP +# define SOAP_SOURCE_STAMP(str) +#endif + +/* gSOAP 2.7.4 and higher: fast look-aside buffering is stable */ +#ifndef WITH_FAST +# define WITH_FAST +#endif + +/* gSOAP 2.7.15 and higher: always retain CDATA in literal XML, unless WITH_LEAN or WITH_NOCDATA */ +#ifndef WITH_LEAN +# ifndef WITH_NOCDATA +# ifndef WITH_CDATA +# define WITH_CDATA +# endif +# endif +#endif + +#ifdef WITH_LEANER +# ifndef WITH_LEAN +# define WITH_LEAN +# endif +#endif + +#ifdef WITH_LEAN +# ifdef WITH_COOKIES +# error "Cannot build WITH_LEAN code WITH_COOKIES enabled" +# endif +#endif + +#ifndef STDSOAP_H +#define STDSOAP_H + +#if defined(__vxworks) || defined(__VXWORKS__) +# ifndef VXWORKS +# define VXWORKS +# endif +#endif + +#ifdef _WIN32 +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef _WIN32_WCE +# ifndef UNDER_CE +# define UNDER_CE _WIN32_WCE +# endif +#endif + +#ifdef UNDER_CE +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef __BORLANDC__ +# ifdef __WIN32__ +# ifndef WIN32 +# define WIN32 +# endif +# endif +#endif + +#ifdef __CYGWIN__ +# ifndef CYGWIN +# define CYGWIN +# endif +#endif + +#ifdef __SYMBIAN32__ +# define SYMBIAN +# undef WIN32 +#endif + +#if defined(__palmos__) || defined(PALM_GCC) || defined(__PALMOS_TRAPS__) +# ifndef PALM +# define PALM +# endif +#endif + +#if defined(__hpux) +# ifndef HP_UX +# define HP_UX +# endif +#endif + +#if defined(__digital__) && defined(__unix__) +# ifndef TRU64 +# define TRU64 +# endif +#endif + +#ifdef __MVS__ +# ifndef OS390 +# define OS390 +# endif +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +# if defined(WITH_OPENSSL) +# ifndef HAVE_OPENSSL_SSL_H +# undef WITH_OPENSSL +# endif +# endif +# if defined(WITH_GNUTLS) +# ifndef HAVE_GNUTLS_GNUTLS_H +# undef WITH_GNUTLS +# endif +# endif +# if defined(WITH_ZLIB) || defined(WITH_GZIP) +# ifndef HAVE_ZLIB_H +# undef WITH_ZLIB +# undef WITH_GZIP +# endif +# endif +#else +# if defined(UNDER_CE) +# define WITH_LEAN +# define HAVE_SSCANF +# elif defined(WIN32) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_GMTIME +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%I64d" +# define SOAP_ULONG_FORMAT "%I64u" +# elif defined(CYGWIN) +# define HAVE_POLL +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__APPLE__) +# define HAVE_POLL +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOD_L +# define HAVE_SSCANF_L +# define HAVE_SPRINTF_L +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(_AIX43) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(_AIX41) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(HP_UX) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(FREEBSD) || defined(__FreeBSD__) || defined(OPENBSD) +# define HAVE_POLL +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOD_L +# define HAVE_SSCANF_L +# define HAVE_SPRINTF_L +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_GETTIMEOFDAY +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%qd" +# define SOAP_ULONG_FORMAT "%qu" +# elif defined(__VMS) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__GLIBC__) || defined(__GNU__) +# define HAVE_POLL +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOD_L +# define HAVE_SSCANF_L +# define HAVE_SPRINTF_L +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define HAVE_ISNAN +# elif defined(TRU64) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_GETTIMEOFDAY +# define HAVE_SYS_TIMEB_H +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define __USE_STD_IOSTREAM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%ld" +# define SOAP_ULONG_FORMAT "%lu" +# elif defined(MAC_CARBON) +# define WITH_NOIO +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOD_L +# define HAVE_SSCANF_L +# define HAVE_SPRINTF_L +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(PALM) +# define WITH_LEAN +# define HAVE_STRTOD /* strtod() is defined in palmFunctions.h */ +# include /* Needs to be included before unix headers */ +# include +# define IGNORE_STDIO_STUBS +# include +# define O_NONBLOCK FNONBIO +# include +# include "palmFunctions.h" +# elif defined(SYMBIAN) +# define WITH_LEAN +# define WITH_NONAMESPACES +# define HAVE_STRTOD /* use STRTOD since sscanf doesn't seem to work */ +# include +# include +# elif defined(VXWORKS) +# ifdef _WRS_KERNEL +# define _POSIX_THREADS 1 +# endif +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_GMTIME +# define HAVE_LOCALTIME +# define HAVE_MKTIME +# elif defined(OS390) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(AS400) +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__QNX__) || defined(QNX) +/* QNX does not have a working version of strtof */ +# undef HAVE_STRTOF +# define HAVE_POLL +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define LONG64 long +# define ULONG64 unsigned LONG64 +# define SOAP_LONG_FORMAT "%ld" +# define SOAP_ULONG_FORMAT "%lu" +# else +/* Default assumptions for supported functions */ +# define HAVE_SNPRINTF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_STRERROR_R +# ifdef MB_LEN_MAX +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# endif +# endif +#endif + +/* native Win and HP-UX compilers don't like empty structs */ +#if defined(WIN32) || defined(HP_UX) || defined(_AIX41) || defined(_AIX43) || defined(VXWORKS) +# define WITH_NOEMPTYSTRUCT +#endif + +#ifdef HP_UX +# undef HAVE_STRTOLL +# undef HAVE_STRTOULL +#endif + +/* older OpenVMS TCP/IP stacks cannot handle 65536 bytes */ +#ifdef __VMS +# ifndef SOAP_BUFLEN +# define SOAP_BUFLEN (65535) +# endif +#endif + +/* if we have xlocale.h we use it to avoid decimal point conversion issues */ +#ifdef WITH_C_LOCALE +# include +# include +#else +# undef HAVE_STRTOF_L +# undef HAVE_STRTOD_L +# undef HAVE_SSCANF_L +# undef HAVE_SPRINTF_L +#endif + +#ifndef WITH_NOSTDLIB +# include +# ifndef PALM +# include +# include +# endif +# include +# include +#endif + +#ifdef HAVE_POLL +# include +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) +# include +# include +#endif + +#ifdef WITH_NOHTTP +# ifndef WITH_NOIO +# define WITH_NOIO +# undef WITH_COOKIES +# endif +#endif + +/* Suggestion when SOAP_FD_EXCEEDED error occurs: + Some systems allow increasing FD_SETSIZE before including sys/types.h: +#define FD_SETSIZE (2048) +*/ + +#ifndef UNDER_CE +# ifndef PALM +# ifndef WITH_NOIO +# include +# include +# endif +# ifndef WITH_LEAN +# ifdef HAVE_SYS_TIMEB_H +# include /* for ftime() */ +# endif +# include +# endif +# endif +#endif + +#ifdef OPENSERVER +# include +# include +# include + extern int h_errno; +#endif + +#ifndef WITH_NOIO +# ifndef WIN32 +# ifndef PALM +# include +# ifdef VXWORKS +# include +# include +# ifndef _WRS_KERNEL +# include +# endif +# else +# ifndef SYMBIAN +# include +# endif +# endif +# ifdef SUN_OS +# include /* SUN */ +# include /* SUN < 2.8 (?) */ +# endif +# ifdef VXWORKS +# ifdef _WRS_KERNEL +# include +# endif +# else +# include +# endif +# include +# ifdef OS390 +# include +# else +# include /* TCP_NODELAY */ +# endif +# include +# endif +# endif +#endif + +#ifdef WIN32 +# define SOAP_WINSOCKINT int +#else +# define SOAP_WINSOCKINT size_t +#endif + +#ifdef WITH_IPV6 +# ifdef IPV6_V6ONLY +# if !defined(WITH_NO_IPV6_V6ONLY) && !defined(WITH_IPV6_V6ONLY) +# define WITH_NO_IPV6_V6ONLY /* turn on IPv6-IPv4 switching */ +# endif +# endif +#endif + +#if defined(WITH_IPV6_V6ONLY) || defined(WITH_NO_IPV6_V6ONLY) +# ifndef WITH_IPV6 +# define WITH_IPV6 +# endif +#endif + +#ifdef WIN32 +# ifndef UNDER_CE +# include +# include +# endif +# ifdef WITH_IPV6 +# include /* Visual Studio 2005 users: you must install the Platform SDK (R2) */ +# include +# include +# define SOAP_GAI_STRERROR gai_strerrorA +# else +# ifndef __BORLANDC__ +# include /* Visual Studio 2005 users: you must install the Platform SDK (R2) */ +/* # include */ /* Alternative: use winsock2 (not available with eVC), enable this line and comment out the line above */ +# else +# include /* Borland C */ +# endif +# endif +#else +# ifdef VXWORKS +# include +# include +# include +# endif +# ifndef WITH_NOIO +# ifndef PALM +# include +# include +# include +# include +# ifdef _AIX41 +# include +# endif +# endif +# endif +#endif + +#ifdef WITH_FASTCGI +# include +#endif + +#ifdef WITH_OPENSSL +# undef WITH_GNUTLS +# define OPENSSL_NO_KRB5 +# include +# include +# include +# include +# include +# ifndef ALLOW_OLD_VERSIONS +# if (OPENSSL_VERSION_NUMBER < 0x00905100L) +# error "Must use OpenSSL 0.9.6 or later" +# endif +# endif +#endif + +#ifdef WITH_GNUTLS +# include +# include +# include +# ifndef HAVE_PTHREAD_H +# ifdef _POSIX_THREADS +# define HAVE_PTHREAD_H /* make GNUTLS thread safe */ +# endif +# endif +#endif + +#ifdef WITH_GZIP +# ifndef WITH_ZLIB +# define WITH_ZLIB +# endif +#endif + +#ifdef WITH_CASEINSENSITIVETAGS +# define SOAP_STRCMP soap_tag_cmp /* case insensitve XML element/attribute names */ +#else +# define SOAP_STRCMP strcmp /* case sensitive XML element/attribute names */ +#endif + +#ifdef WITH_ZLIB +# include +#endif + +#ifndef WITH_NOSTDLIB +# ifndef PALM +# include /* for isnan() */ +# endif +#endif + +/* #define DEBUG */ /* Uncomment to debug sending (in file SENT.log) receiving (in file RECV.log) and messages (in file TEST.log) */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Portability: define SOAP_SOCKLEN_T */ +#if defined(_AIX) +# if defined(_AIX43) +# define SOAP_SOCKLEN_T socklen_t +# else +# define SOAP_SOCKLEN_T int +# endif +#elif defined(SOCKLEN_T) +# define SOAP_SOCKLEN_T SOCKLEN_T +#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) || defined(FREEBSD) || defined(__FreeBSD__) || defined(OPENBSD) || defined(__QNX__) || defined(QNX) || defined(OS390) || defined(HP_UX) +# define SOAP_SOCKLEN_T socklen_t +#elif defined(IRIX) || defined(WIN32) || defined(__APPLE__) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS) +# define SOAP_SOCKLEN_T int +#else +# define SOAP_SOCKLEN_T size_t +#endif + +#ifndef SOAP_SOCKET +# ifdef WIN32 +# define SOAP_SOCKET SOCKET +# define soap_closesocket(n) closesocket(n) +# else +# define SOAP_SOCKET int +# define soap_closesocket(n) close(n) +# endif +#endif + +#define SOAP_INVALID_SOCKET ((SOAP_SOCKET)-1) +#define soap_valid_socket(n) ((n) != SOAP_INVALID_SOCKET) + +#define SOAP_SHUT_WR 1 +#define SOAP_SHUT_RDWR 2 + +#ifndef SOAP_GAI_STRERROR +# define SOAP_GAI_STRERROR gai_strerror +#endif + +#ifndef FD_SETSIZE +# define FD_SETSIZE (1024) +#endif + +#if defined(SYMBIAN) +# define LONG64 long +# define ULONG64 unsigned LONG64 +#elif !defined(WIN32) || defined(CYGWIN) || defined(__GLIBC__) || defined(__GNU__) +# ifndef LONG64 +# if defined(HAVE_STDINT_H) +# include +# define LONG64 int64_t +# define ULONG64 uint64_t +# elif defined(__GLIBC__) +# include +# if (__WORDSIZE == 64) +# define LONG64 int64_t +# define ULONG64 uint64_t +# ifndef SOAP_LONG_FORMAT +# define SOAP_LONG_FORMAT "%ld" +# endif +# ifndef SOAP_ULONG_FORMAT +# define SOAP_ULONG_FORMAT "%lu" +# endif +# else +# define LONG64 long long +# define ULONG64 unsigned LONG64 +# endif +# else +# define LONG64 long long +# define ULONG64 unsigned LONG64 +# endif +# endif +#elif defined(UNDER_CE) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#elif defined(__BORLANDC__) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#endif + +#ifndef SOAP_LONG_FORMAT +# define SOAP_LONG_FORMAT "%lld" /* printf format for 64 bit ints */ +#endif + +#ifndef SOAP_ULONG_FORMAT +# define SOAP_ULONG_FORMAT "%llu" /* printf format for unsigned 64 bit ints */ +#endif + +#if defined(WIN32) && !defined(CYGWIN) +# define soap_int32 __int32 +#elif defined(SYMBIAN) +# define soap_int32 long +#elif defined(PALM) +# define soap_int32 Int32 +#elif defined(_AIX) +# define SOAP_NEW(type) new type /* AIX compilers don't like new (t) */ +# if defined(_AIX43) +# define soap_int32 int32_t +# else +# define soap_int32 signed int +# endif +#else +# define soap_int32 int32_t +#endif + +#ifdef WIN32 +# define SOAP_ERANGE ERANGE +# define SOAP_EINTR WSAEINTR +# define SOAP_EAGAIN WSAEWOULDBLOCK +# define SOAP_EWOULDBLOCK WSAEWOULDBLOCK +# define SOAP_EINPROGRESS WSAEINPROGRESS +# define SOAP_EADDRINUSE WSAEADDRINUSE +#else +# define SOAP_ERANGE ERANGE +# define SOAP_EINTR EINTR +# define SOAP_EAGAIN EAGAIN +# define SOAP_EADDRINUSE EADDRINUSE +# ifdef SYMBIAN +# define SOAP_EWOULDBLOCK 9898 +# define SOAP_EINPROGRESS 9899 +# else +# define SOAP_EWOULDBLOCK EWOULDBLOCK +# define SOAP_EINPROGRESS EINPROGRESS +# endif +#endif + +#ifdef WIN32 +# ifdef UNDER_CE +# define soap_errno GetLastError() +# define soap_socket_errno(s) GetLastError() +# define soap_reset_errno SetLastError(0) +# else +# define soap_errno GetLastError() +# define soap_socket_errno(s) WSAGetLastError() +# define soap_reset_errno SetLastError(0) +# endif +#else +# ifndef WITH_NOIO +# define soap_errno errno +# define soap_socket_errno(s) errno +# define soap_reset_errno (errno = 0) +# else +# define soap_errno 0 +# define soap_socket_errno(s) 0 +# define soap_reset_errno +# endif +#endif + +#ifndef SOAP_BUFLEN +# if !defined(WITH_LEAN) +# define SOAP_BUFLEN (65536) /* buffer length for socket packets, also used by gethostbyname_r and UDP messages, so don't make this too small */ +# else +# define SOAP_BUFLEN (2048) /* lean size */ +# endif +#endif +#ifndef SOAP_LABLEN +# define SOAP_LABLEN (256) /* initial look-aside buffer length */ +#endif +#ifndef SOAP_PTRBLK +# define SOAP_PTRBLK (32) /* block allocation for pointer hash table chains */ +#endif +#ifndef SOAP_PTRHASH +# ifndef WITH_LEAN +# define SOAP_PTRHASH (1024) /* size of pointer analysis hash table (must be power of 2) */ +# else +# define SOAP_PTRHASH (32) +# endif +#endif +#ifndef SOAP_IDHASH +# ifndef WITH_LEAN +# define SOAP_IDHASH (1999) /* prime size of hash table for parsed id/ref */ +# else +# define SOAP_IDHASH (19) /* 19, 199 */ +# endif +#endif +#ifndef SOAP_BLKLEN +# ifndef WITH_LEAN +# define SOAP_BLKLEN (256) /* size of blocks to collect long strings and XML attributes */ +# else +# define SOAP_BLKLEN (32) +# endif +#endif +#ifndef SOAP_TAGLEN +# ifndef WITH_LEAN +# define SOAP_TAGLEN (1024) /* maximum length of XML element tag/attribute name or host/path name + 1 */ +# else +# define SOAP_TAGLEN (128) +# endif +#endif +#ifndef SOAP_HDRLEN +# ifndef WITH_LEAN +# define SOAP_HDRLEN (8192) /* maximum length of HTTP header line (must be >4096 to read cookies) */ +# else +# define SOAP_HDRLEN (1024) +# endif +#endif +#ifndef SOAP_MAXDIMS +# ifndef WITH_LEAN +# define SOAP_MAXDIMS (16) /* maximum array dimensions (array nestings) must be less than 64 to protect soap->tmpbuf */ +# else +# define SOAP_MAXDIMS (4) +# endif +#endif + +#ifndef SOAP_MAXLOGS +# define SOAP_MAXLOGS (3) /* max number of debug logs per struct soap environment */ +# define SOAP_INDEX_RECV (0) +# define SOAP_INDEX_SENT (1) +# define SOAP_INDEX_TEST (2) +#endif + +/* Max iterations in soap_serve() to keep server connection alive */ +#ifndef SOAP_MAXKEEPALIVE +# define SOAP_MAXKEEPALIVE (100) +#endif + +/* Trusted max size of inbound SOAP array for compound array allocation. + Increase if necessary to allow larger arrays. +*/ +#ifndef SOAP_MAXARRAYSIZE +# define SOAP_MAXARRAYSIZE (1000000) +#endif + +#ifdef VXWORKS +# ifdef WMW_RPM_IO +# include "httpLib.h" +# endif +# ifdef __INCmathh +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# ifndef soap_isnan +# define soap_isnan(num) isNan(num) +# endif +# endif +# ifdef WM_SECURE_KEY_STORAGE +# include +# endif +#endif + +#ifdef WIN32 +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) _isnan(num) +#endif + +#ifdef SUN_OS +# define HAVE_ISNAN +#endif + +#ifdef __APPLE__ +# ifdef __cplusplus +# ifndef isnan +extern "C" int isnan(double); +# endif +# endif +# define HAVE_ISNAN +#endif + +#if !defined(HAVE_ISNAN) && (defined(_MATH_H) || defined(_MATH_INCLUDED)) +# define HAVE_ISNAN +#endif + +extern const struct soap_double_nan { unsigned int n1, n2; } soap_double_nan; + +#ifdef VXWORKS +# ifndef FLT_MAX +# define FLT_MAX _ARCH_FLT_MAX +# endif +# ifndef DBL_MAX +# define DBL_MAX _ARCH_DBL_MAX +# endif +#endif + +#ifndef FLT_NAN +# define FLT_NAN (*(float*)(void*)&soap_double_nan) +#endif + +#ifndef FLT_PINFTY +# if defined(FLT_MAX) +# define FLT_PINFTY FLT_MAX +# elif defined(HUGE_VALF) +# define FLT_PINFTY (float)HUGE_VALF +# elif defined(HUGE_VAL) +# define FLT_PINFTY (float)HUGE_VAL +# elif defined(FLOAT_MAX) +# define FLT_PINFTY FLOAT_MAX +# else +# define FLT_PINFTY (3.40282347e+38F) +# endif +#endif + +#ifndef FLT_NINFTY +# define FLT_NINFTY (-FLT_PINFTY) +#endif + +#ifndef DBL_NAN +# define DBL_NAN (*(double*)(void*)&soap_double_nan) +#endif + +#ifndef DBL_PINFTY +# if defined(DBL_MAX) +# define DBL_PINFTY DBL_MAX +# elif defined(HUGE_VALF) +# define DBL_PINFTY (double)HUGE_VALF +# elif defined(HUGE_VAL) +# define DBL_PINFTY (double)HUGE_VAL +# elif defined(DOUBLE_MAX) +# define DBL_PINFTY DOUBLE_MAX +# else +# define DBL_PINFTY (1.7976931348623157e+308) +# endif +#endif + +#ifndef DBL_NINFTY +# define DBL_NINFTY (-DBL_PINFTY) +#endif + +#ifndef soap_isnan +# ifdef HAVE_ISNAN +# define soap_isnan(n) isnan(n) +# else +# define soap_isnan(n) (0) +# endif +#endif + +#define soap_ispinfd(n) ((n) >= DBL_PINFTY) +#define soap_ispinff(n) ((n) >= FLT_PINFTY) +#define soap_isninfd(n) ((n) <= DBL_NINFTY) +#define soap_isninff(n) ((n) <= FLT_NINFTY) + +/* gSOAP error codes */ + +#define SOAP_EOF EOF +#define SOAP_ERR EOF +#define SOAP_OK 0 +#define SOAP_CLI_FAULT 1 +#define SOAP_SVR_FAULT 2 +#define SOAP_TAG_MISMATCH 3 +#define SOAP_TYPE 4 +#define SOAP_SYNTAX_ERROR 5 +#define SOAP_NO_TAG 6 +#define SOAP_IOB 7 +#define SOAP_MUSTUNDERSTAND 8 +#define SOAP_NAMESPACE 9 +#define SOAP_USER_ERROR 10 +#define SOAP_FATAL_ERROR 11 +#define SOAP_FAULT 12 +#define SOAP_NO_METHOD 13 +#define SOAP_NO_DATA 14 +#define SOAP_GET_METHOD 15 +#define SOAP_PUT_METHOD 16 +#define SOAP_DEL_METHOD 17 /* deprecated */ +#define SOAP_HEAD_METHOD 18 /* deprecated */ +#define SOAP_HTTP_METHOD 19 +#define SOAP_EOM 20 +#define SOAP_MOE 21 +#define SOAP_HDR 22 +#define SOAP_NULL 23 +#define SOAP_DUPLICATE_ID 24 +#define SOAP_MISSING_ID 25 +#define SOAP_HREF 26 +#define SOAP_UDP_ERROR 27 +#define SOAP_TCP_ERROR 28 +#define SOAP_HTTP_ERROR 29 +#define SOAP_SSL_ERROR 30 +#define SOAP_ZLIB_ERROR 31 +#define SOAP_DIME_ERROR 32 +#define SOAP_DIME_HREF 33 +#define SOAP_DIME_MISMATCH 34 +#define SOAP_DIME_END 35 +#define SOAP_MIME_ERROR 36 +#define SOAP_MIME_HREF 37 +#define SOAP_MIME_END 38 +#define SOAP_VERSIONMISMATCH 39 +#define SOAP_PLUGIN_ERROR 40 +#define SOAP_DATAENCODINGUNKNOWN 41 +#define SOAP_REQUIRED 42 +#define SOAP_PROHIBITED 43 +#define SOAP_OCCURS 44 +#define SOAP_LENGTH 45 +#define SOAP_FD_EXCEEDED 46 + +#define soap_xml_error_check(e) ((e) == SOAP_TAG_MISMATCH || (e) == SOAP_NO_TAG || (e) == SOAP_SYNTAX_ERROR || (e) == SOAP_NAMESPACE || (e) == SOAP_DUPLICATE_ID || (e) == SOAP_MISSING_ID || (e) == SOAP_REQUIRED || (e) == SOAP_PROHIBITED || (e) == SOAP_OCCURS || (e) == SOAP_LENGTH || (e) == SOAP_NULL || (e) == SOAP_HREF) +#define soap_soap_error_check(e) ((e) == SOAP_CLI_FAULT || (e) == SOAP_SVR_FAULT || (e) == SOAP_VERSIONMISMATCH || (e) == SOAP_MUSTUNDERSTAND || (e) == SOAP_FAULT || (e) == SOAP_NO_METHOD) +#define soap_tcp_error_check(e) ((e) == SOAP_EOF || (e) == SOAP_TCP_ERROR) +#define soap_ssl_error_check(e) ((e) == SOAP_SSL_ERROR) +#define soap_zlib_error_check(e) ((e) == SOAP_ZLIB_ERROR) +#define soap_http_error_check(e) ((e) == SOAP_HTTP_ERROR || (e) == SOAP_NO_DATA || ((e) >= SOAP_GET_METHOD && (e) <= SOAP_HTTP_METHOD) || ((e) >= 100 && (e) < 600)) + +/* gSOAP HTTP response status codes 100 to 599 are reserved */ + +/* Codes 600 to 999 are user definable */ + +/* Exceptional gSOAP HTTP server response status codes >= 1000 */ + +#define SOAP_STOP 1000 /* No HTTP response */ +#define SOAP_FORM 1001 /* Form request/response */ +#define SOAP_HTML 1002 /* Custom HTML response */ +#define SOAP_FILE 1003 /* Custom file-based response */ + +/* gSOAP HTTP method codes (client) */ + +#define SOAP_POST 2000 /* POST request */ +#define SOAP_POST_FILE 2001 /* Custom file-based POST request */ +#define SOAP_GET 2002 /* GET request */ + +/* gSOAP DIME */ + +#define SOAP_DIME_CF 0x01 +#define SOAP_DIME_ME 0x02 +#define SOAP_DIME_MB 0x04 +#define SOAP_DIME_VERSION 0x08 /* DIME version 1 */ +#define SOAP_DIME_MEDIA 0x10 +#define SOAP_DIME_ABSURI 0x20 + +/* gSOAP ZLIB */ + +#define SOAP_ZLIB_NONE 0x00 +#define SOAP_ZLIB_DEFLATE 0x01 +#define SOAP_ZLIB_INFLATE 0x02 +#define SOAP_ZLIB_GZIP 0x02 + +/* gSOAP transport, connection, and content encoding modes */ + +typedef soap_int32 soap_mode; + +#define SOAP_IO 0x00000003 /* IO mask */ +#define SOAP_IO_FLUSH 0x00000000 /* flush output immediately, no buffering */ +#define SOAP_IO_BUFFER 0x00000001 /* buffer output in packets of size SOAP_BUFLEN */ +#define SOAP_IO_STORE 0x00000002 /* store entire output to determine length for transport */ +#define SOAP_IO_CHUNK 0x00000003 /* use HTTP chunked transfer AND buffer packets */ + +#define SOAP_IO_UDP 0x00000004 /* TCP or UDP */ +#define SOAP_IO_LENGTH 0x00000008 /* calc message length (internal) */ +#define SOAP_IO_KEEPALIVE 0x00000010 /* keep connection alive */ + +#define SOAP_ENC 0x00000FFF /* IO and ENC mask */ +#define SOAP_ENC_LATIN 0x00000020 /* in: accept iso-8859-1 */ +#define SOAP_ENC_XML 0x00000040 /* out: plain XML encoding, no HTTP header */ +#define SOAP_ENC_DIME 0x00000080 +#define SOAP_ENC_MIME 0x00000100 +#define SOAP_ENC_MTOM 0x00000200 +#define SOAP_ENC_ZLIB 0x00000400 +#define SOAP_ENC_SSL 0x00000800 + +#define SOAP_XML_STRICT 0x00001000 /* in: strict validation */ +#define SOAP_XML_INDENT 0x00002000 /* out: emit indented XML */ +#define SOAP_XML_IGNORENS 0x00004000 /* in: ignore namespaces */ +#define SOAP_XML_DEFAULTNS 0x00008000 /* out: emit xmlns="..." */ +#define SOAP_XML_CANONICAL 0x00010000 /* out: excC14N canonical XML */ +#define SOAP_XML_TREE 0x00020000 /* out: XML tree (no id/ref) */ +#define SOAP_XML_GRAPH 0x00040000 /* see DOM manual */ +#define SOAP_XML_NIL 0x00080000 /* out: NULLs as xsi:nil */ + +#define SOAP_C_NOIOB 0x00100000 /* don't fault on array index out of bounds (just ignore) */ +#define SOAP_C_UTFSTRING 0x00200000 /* (de)serialize strings with UTF8 content */ +#define SOAP_C_MBSTRING 0x00400000 /* (de)serialize strings with multi-byte content */ +#define SOAP_C_NILSTRING 0x00800000 /* serialize empty strings as nil (omitted) */ + +#define SOAP_XML_DOM 0x01000000 + +#define SOAP_DOM_TREE 0x02000000 +#define SOAP_DOM_NODE 0x04000000 +#define SOAP_DOM_ASIS 0x08000000 + +#define SOAP_MIME_POSTCHECK 0x10000000 /* MIME flag (internal) */ + +#define SOAP_XML_SEC 0x80000000 /* reserved for WS security */ + +/* WITH_XMLNS backward compatibility: always use XML default namespaces */ +#ifdef WITH_XMLNS +# define SOAP_IO_DEFAULT (SOAP_IO_FLUSH | SOAP_XML_DEFAULTNS) +#else +# define SOAP_IO_DEFAULT SOAP_IO_FLUSH +#endif + +/* SSL client/server authentication settings */ + +#define SOAP_SSL_NO_AUTHENTICATION 0x00 /* for testing purposes */ +#define SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION 0x01 /* client requires server to authenticate */ +#define SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION 0x02 /* server requires client to authenticate */ +#define SOAP_SSL_SKIP_HOST_CHECK 0x04 /* client does not check the common name of the host in certificate */ +#define SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE 0x08 /* client does not check the expiration date of the host certificate */ +#define SOAP_SSL_NO_DEFAULT_CA_PATH 0x10 /* don't use default_verify_paths */ +#define SOAP_SSL_RSA 0x20 /* use RSA */ +#define SOAP_SSLv3 0x40 /* SSL v3 only */ +#define SOAP_TLSv1 0x80 /* TLS v1 only */ +#define SOAP_SSLv3_TLSv1 0x00 /* SSL v3 and TLS v1 support by default (no SSL v1/v2) */ +#define SOAP_SSL_CLIENT 0x100 /* client context */ + +#define SOAP_SSL_DEFAULT (SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION | SOAP_SSLv3_TLSv1) + +/* state */ + +#define SOAP_NONE 0 +#define SOAP_INIT 1 +#define SOAP_COPY 2 + +#define soap_check_state(soap) (!(soap) || ((soap)->state != SOAP_INIT && (soap)->state != SOAP_COPY)) + +/* part */ + +#define SOAP_BEGIN 0 +#define SOAP_IN_ENVELOPE 2 +#define SOAP_IN_HEADER 3 +#define SOAP_END_HEADER 4 +#define SOAP_NO_BODY 5 +#define SOAP_IN_BODY 6 +#define SOAP_END_BODY 7 +#define SOAP_END_ENVELOPE 8 +#define SOAP_END 9 +#define SOAP_BEGIN_SECURITY 10 +#define SOAP_IN_SECURITY 11 +#define SOAP_END_SECURITY 12 + +/* DEBUG macros */ + +#ifndef WITH_LEAN +# ifdef DEBUG +# ifndef SOAP_DEBUG +# define SOAP_DEBUG +# endif +# ifndef SOAP_MEM_DEBUG +# define SOAP_MEM_DEBUG +# endif +# endif +#endif + +#ifdef SOAP_MEM_DEBUG +# ifndef SOAP_MALLOC +# define SOAP_MALLOC(soap, size) soap_track_malloc(soap, __FILE__, __LINE__, size) +# endif +# ifndef SOAP_FREE +# define SOAP_FREE(soap, ptr) soap_track_free(soap, __FILE__, __LINE__, ptr) +# endif +#endif + +#ifndef SOAP_MALLOC /* use libc malloc */ +# define SOAP_MALLOC(soap, size) malloc(size) +#endif + +#ifndef SOAP_FREE /* use libc free */ +# define SOAP_FREE(soap, ptr) free(ptr) +#endif + +#ifndef SOAP_NEW /* use C++ new operator */ +# if __GNUC__ <= 2 +# define SOAP_NEW(type) new type /* old form w/o parenthesis */ +# else +# define SOAP_NEW(type) new (type) /* with parenthesis */ +# endif +#endif + +#ifndef SOAP_NEW_COPY /* use C++ new operator for ::copy() */ +# define SOAP_NEW_COPY(clas) new clas +#endif + +#ifndef SOAP_DELETE /* use C++ delete operator */ +# define SOAP_DELETE(obj) delete obj +#endif + +#ifndef SOAP_DELETE_ARRAY /* use C++ delete[] operator */ +# define SOAP_DELETE_ARRAY(obj) delete[] obj +#endif + +#ifdef SOAP_DEBUG +# ifndef SOAP_MESSAGE +# define SOAP_MESSAGE fprintf +# endif +# ifndef DBGLOG +# define DBGLOG(DBGFILE, CMD) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile((struct soap*)soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { FILE *fdebug = soap->fdebug[SOAP_INDEX_##DBGFILE];\ + CMD;\ + fflush(fdebug);\ + }\ + }\ +} +# endif +# ifndef DBGMSG +# define DBGMSG(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile((struct soap*)soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { fwrite((MSG), 1, (LEN), soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +# ifndef DBGFUN +# define DBGFUN(FNAME) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s()\n", __FILE__, __LINE__, FNAME)) +# define DBGFUN1(FNAME, FMT, ARG) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT")\n", __FILE__, __LINE__, FNAME, (ARG))) +# define DBGFUN2(FNAME, FMT1, ARG1, FMT2, ARG2) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT1", "FMT2")\n", __FILE__, __LINE__, FNAME, (ARG1), (ARG2))) +# define DBGFUN3(FNAME, FMT1, ARG1, FMT2, ARG2, FMT3, ARG3) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT1", "FMT2", "FMT3")\n", __FILE__, __LINE__, FNAME, (ARG1), (ARG2), (ARG3))) +# endif +# ifndef DBGHEX +# define DBGHEX(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { int i; char *s;\ + for (s = (char*)(MSG), i = (LEN); i; i--)\ + fprintf(soap->fdebug[SOAP_INDEX_##DBGFILE], "%2.2X ", (int)*s++&0xFF);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +#else +# define DBGLOG(DBGFILE, CMD) +# define DBGMSG(DBGFILE, MSG, LEN) +# define DBGFUN(FNAME) +# define DBGFUN1(FNAME, FMT, ARG) +# define DBGFUN2(FNAME, FMT1, ARG1, FMT2, ARG2) +# define DBGFUN3(FNAME, FMT1, ARG1, FMT2, ARG2, FMT3, ARG3) +# define DBGHEX(DBGFILE, MSG, LEN) +#endif + +/* UCS-4 requires 32 bits (0-7FFFFFFF, the sign bit is used by gSOAP to distinguish XML entities) */ +typedef soap_int32 soap_wchar; + +/* namespace table row */ +struct Namespace +{ const char *id; + const char *ns; + const char *in; + char *out; +}; + +/* namespace stack */ +struct soap_nlist +{ struct soap_nlist *next; + unsigned int level; /* nesting depth level */ + short index; /* corresponding entry in ns mapping table */ + const char *ns; /* only set when parsed ns URI is not in the ns mapping table */ + char id[1]; /* the actual string value flows into the allocated region below this struct */ +}; + +/* block stack for nested block allocations */ +struct soap_blist +{ struct soap_blist *next; + char *ptr; + size_t size; +}; + +/* array layout */ +struct soap_array +{ void *__ptr; + int __size; +}; + +/* pointer serialization management */ +struct soap_plist +{ struct soap_plist *next; + const void *ptr; + const struct soap_array *array; + int type; + int id; + char mark1; + char mark2; +}; + +/* block allocation for pointer serialization management */ +struct soap_pblk +{ struct soap_pblk *next; + struct soap_plist plist[SOAP_PTRBLK]; +}; + +#ifdef SOAP_MEM_DEBUG +/* malloc/free tracking for debugging */ +struct soap_mlist +{ struct soap_mlist *next; + const void *ptr; + const char *file; + int line; + short live; +}; +#endif + +/* class allocation list */ +struct soap_clist +{ struct soap_clist *next; + void *ptr; + int type; + int size; + int (*fdelete)(struct soap_clist*); +}; + +/* attributes */ +struct soap_attribute +{ struct soap_attribute *next; + short flag; /* soap_set_attr: 1 = normal, 2 = utf content */ + char *value; + size_t size; + char *ns; + short visible; + char name[1]; /* the actual name string flows into the allocated region below this struct */ +}; + +#ifndef WITH_LEAN +struct soap_cookie +{ struct soap_cookie *next; + char *name; + char *value; + char *domain; + char *path; + time_t expire; /* client-side: local time to expire */ + long maxage; /* server-side: seconds to expire */ + unsigned int version; + short secure; + short session; /* server-side */ + short env; /* server-side: got cookie from client and should not be (re)send */ + short modified; /* server-side: client cookie was modified and should be send */ +}; +#endif + +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); + +#ifdef __cplusplus + +class soap_multipart_iterator +{ public: + struct soap_multipart *content; + bool operator==(const soap_multipart_iterator& iter) const + { return (bool)(content == iter.content); } + bool operator!=(const soap_multipart_iterator& iter) const + { return (bool)(content != iter.content); } + struct soap_multipart &operator*() const + { return *content; } + soap_multipart_iterator &operator++() + { content = soap_next_multipart(content); return *this; } + soap_multipart_iterator() : content(NULL) + { } + soap_multipart_iterator(struct soap_multipart *p) : content(p) + { } +}; +#endif + +#ifndef WITH_LEANER +struct soap_dime +{ size_t count; + size_t size; + size_t chunksize; + size_t buflen; + char flags; + char *ptr; + const char *id; + const char *type; + const char *options; + struct soap_multipart *list; /* list of DIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +struct soap_mime +{ char *boundary; /* MIME boundary */ + const char *start; /* MIME start ID */ + struct soap_multipart *list; /* list of MIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* RFC2045 MIME content transfer encodings */ +enum soap_mime_encoding +{ SOAP_MIME_NONE, + SOAP_MIME_7BIT, + SOAP_MIME_8BIT, + SOAP_MIME_BINARY, + SOAP_MIME_QUOTED_PRINTABLE, + SOAP_MIME_BASE64, + SOAP_MIME_IETF_TOKEN, + SOAP_MIME_X_TOKEN +}; +#endif + +#ifndef WITH_LEANER +/* DIME/MIME multipart list */ +struct soap_multipart +{ struct soap_multipart *next; + char *ptr; /* points to raw data content */ + size_t size; /* size of data content */ + const char *id; /* DIME/MIME content ID or form data name */ + const char *type; /* DIME/MIME type (MIME type format) */ + const char *options; /* DIME options */ + enum soap_mime_encoding encoding; /* MIME Content-Transfer-Encoding */ + const char *location; /* MIME Content-Location (optional) */ + const char *description; /* MIME Content-Description (optional) */ +#ifdef __cplusplus + typedef soap_multipart_iterator iterator; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* attachment DIME and MTOM XOP forwarding */ +struct soap_xlist +{ struct soap_xlist *next; + unsigned char **ptr; + int *size; + char *id; + char **type; + char **options; +}; +#endif + +/******************************************************************************/ + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_attribute_iterator +{ public: + struct soap_dom_attribute *att; + const char *nstr; + const char *name; + bool operator==(const soap_dom_attribute_iterator&) const; + bool operator!=(const soap_dom_attribute_iterator&) const; + struct soap_dom_attribute &operator*() const; + soap_dom_attribute_iterator &operator++(); + soap_dom_attribute_iterator(); + soap_dom_attribute_iterator(struct soap_dom_attribute*); + ~soap_dom_attribute_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_attribute +{ struct soap_dom_attribute *next; + const char *nstr; + char *name; + char *data; + wchar_t *wide; + struct soap *soap; +#ifdef __cplusplus + typedef soap_dom_attribute_iterator iterator; + struct soap_dom_attribute &set(const char *nstr, const char *name); /* set namespace and name */ + struct soap_dom_attribute &set(const char *data); /* set data */ + soap_dom_attribute_iterator begin(); + soap_dom_attribute_iterator end(); + soap_dom_attribute_iterator find(const char *nstr, const char *name); + void unlink(); + soap_dom_attribute(); + soap_dom_attribute(struct soap *soap); + soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data); + ~soap_dom_attribute(); +#endif +}; +#endif + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_element_iterator +{ public: + struct soap_dom_element *elt; + const char *nstr; + const char *name; + int type; + bool operator==(const soap_dom_element_iterator&) const; + bool operator!=(const soap_dom_element_iterator&) const; + struct soap_dom_element &operator*() const; + soap_dom_element_iterator &operator++(); + soap_dom_element_iterator(); + soap_dom_element_iterator(struct soap_dom_element*); + ~soap_dom_element_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_element +{ struct soap_dom_element *next; /* next sibling */ + struct soap_dom_element *prnt; /* parent */ + struct soap_dom_element *elts; /* list of child elements */ + struct soap_dom_attribute *atts; /* list of attributes */ + const char *nstr; /* namespace string */ + char *name; /* element tag name */ + char *data; /* element content data (with SOAP_C_UTFSTRING flag set) */ + wchar_t *wide; /* element content data */ + int type; /* optional: serialized C/C++ data type */ + void *node; /* optional: pointer to serialized C/C++ data */ + char *head; /* leading content before start tag */ + char *tail; /* leading content before end tag */ + struct soap *soap; /* soap context that manages this node */ +#ifdef __cplusplus + typedef soap_dom_element_iterator iterator; + struct soap_dom_element &set(const char *nstr, const char *name); + struct soap_dom_element &set(const char *data); + struct soap_dom_element &set(void *node, int type); + struct soap_dom_element &add(struct soap_dom_element*); + struct soap_dom_element &add(struct soap_dom_element&); + struct soap_dom_element &add(struct soap_dom_attribute*); + struct soap_dom_element &add(struct soap_dom_attribute&); + soap_dom_element_iterator begin(); + soap_dom_element_iterator end(); + soap_dom_element_iterator find(const char *nstr, const char *name); + soap_dom_element_iterator find(int type); + void unlink(); + soap_dom_element(); + soap_dom_element(struct soap *soap); + soap_dom_element(struct soap *soap, const char *nstr, const char *name); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type); + ~soap_dom_element(); +#endif +}; +SOAP_FMAC1 struct soap_dom_element * SOAP_FMAC2 soap_dom_next_element(struct soap_dom_element *elt); +SOAP_FMAC1 struct soap_dom_attribute * SOAP_FMAC2 soap_dom_next_attribute(struct soap_dom_attribute *att); +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) +} +extern std::ostream &operator<<(std::ostream&, const struct soap_dom_element&); +extern std::istream &operator>>(std::istream&, struct soap_dom_element&); +extern "C" { +#endif + +/******************************************************************************/ + +#ifdef WIN32 +# ifdef SOAP_STD_EXPORTS +# define SOAP_STD_API __declspec(dllexport) +# else +# define SOAP_STD_API +# endif +#else +# define SOAP_STD_API +#endif + +struct SOAP_STD_API soap +{ short state; /* 0 = uninitialized, 1 = initialized, 2 = copy of another soap struct */ + short version; /* 1 = SOAP1.1 and 2 = SOAP1.2 (set automatically from namespace URI in nsmap table) */ + soap_mode mode; + soap_mode imode; + soap_mode omode; + const char *float_format; /* user-definable format string for floats (<1024 chars) */ + const char *double_format; /* user-definable format string for doubles (<1024 chars) */ + const char *dime_id_format; /* user-definable format string for integer DIME id ( 0, gives socket recv timeout in seconds, < 0 in usec */ + int send_timeout; /* when > 0, gives socket send timeout in seconds, < 0 in usec */ + int connect_timeout; /* when > 0, gives socket connect() timeout in seconds, < 0 in usec */ + int accept_timeout; /* when > 0, gives socket accept() timeout in seconds, < 0 in usec */ + int socket_flags; /* socket recv() and send() flags, e.g. set to MSG_NOSIGNAL to disable sigpipe */ + int connect_flags; /* connect() SOL_SOCKET sockopt flags, e.g. set to SO_DEBUG to debug socket */ + int bind_flags; /* bind() SOL_SOCKET sockopt flags, e.g. set to SO_REUSEADDR to enable reuse */ + int accept_flags; /* accept() SOL_SOCKET sockopt flags */ + unsigned short linger_time; /* linger time for SO_LINGER option */ + const struct Namespace *namespaces; /* Pointer to global namespace mapping table */ + struct Namespace *local_namespaces; /* Local namespace mapping table */ + struct soap_nlist *nlist; /* namespace stack */ + struct soap_blist *blist; /* block allocation stack */ + struct soap_clist *clist; /* class instance allocation list */ + void *alist; /* memory allocation (malloc) list */ + struct soap_ilist *iht[SOAP_IDHASH]; + struct soap_plist *pht[SOAP_PTRHASH]; + struct soap_pblk *pblk; /* plist block allocation */ + short pidx; /* plist block allocation */ + struct SOAP_ENV__Header *header; + struct SOAP_ENV__Fault *fault; + int idnum; + void *user; /* to pass user-defined data */ + struct soap_plugin *plugins; /* linked list of plug-in data */ + const char *userid; /* HTTP Basic authorization userid */ + const char *passwd; /* HTTP Basic authorization passwd */ + int (*fpost)(struct soap*, const char*, const char*, int, const char*, const char*, size_t); + int (*fget)(struct soap*); /* HTTP GET hook (not set by default) */ + int (*fput)(struct soap*); /* HTTP PUT hook (handled as POST) */ + int (*fdel)(struct soap*); /* HTTP DELETE hook (not set by default) */ + int (*fopt)(struct soap*); /* HTTP OPTIONS hook (not set by default) */ + int (*fhead)(struct soap*); /* HTTP HEAD hook (not set by default) */ + int (*fform)(struct soap*); /* HTTP/HTML form handler for plugins */ + int (*fposthdr)(struct soap*, const char*, const char*); + int (*fresponse)(struct soap*, int, size_t); + int (*fparse)(struct soap*); + int (*fparsehdr)(struct soap*, const char*, const char*); + int (*fheader)(struct soap*); + int (*fresolve)(struct soap*, const char*, struct in_addr* inaddr); + int (*fconnect)(struct soap*, const char*, const char*, int); + int (*fdisconnect)(struct soap*); + int (*fclosesocket)(struct soap*, SOAP_SOCKET); + int (*fshutdownsocket)(struct soap*, SOAP_SOCKET, int); + SOAP_SOCKET (*fopen)(struct soap*, const char*, const char*, int); + SOAP_SOCKET (*faccept)(struct soap*, SOAP_SOCKET, struct sockaddr*, int *n); + int (*fclose)(struct soap*); + int (*fsend)(struct soap*, const char*, size_t); + size_t (*frecv)(struct soap*, char*, size_t); + int (*fpoll)(struct soap*); + void (*fseterror)(struct soap*, const char **c, const char **s); + int (*fignore)(struct soap*, const char*); + int (*fserveloop)(struct soap*); + void *(*fplugin)(struct soap*, const char*); + void *(*fmalloc)(struct soap*, size_t); +#ifndef WITH_LEANER + int (*fprepareinitsend)(struct soap*); + int (*fprepareinitrecv)(struct soap*); + int (*fpreparesend)(struct soap*, const char*, size_t); + int (*fpreparerecv)(struct soap*, const char*, size_t); + int (*fpreparefinalsend)(struct soap*); + int (*fpreparefinalrecv)(struct soap*); + void *(*fdimereadopen)(struct soap*, void*, const char*, const char*, const char*); + void *(*fdimewriteopen)(struct soap*, const char*, const char*, const char*); + void (*fdimereadclose)(struct soap*, void*); + void (*fdimewriteclose)(struct soap*, void*); + size_t (*fdimeread)(struct soap*, void*, char*, size_t); + int (*fdimewrite)(struct soap*, void*, const char*, size_t); + void *(*fmimereadopen)(struct soap*, void*, const char*, const char*, const char*); + void *(*fmimewriteopen)(struct soap*, void*, const char*, const char*, const char*, enum soap_mime_encoding); + void (*fmimereadclose)(struct soap*, void*); + void (*fmimewriteclose)(struct soap*, void*); + size_t (*fmimeread)(struct soap*, void*, char*, size_t); + int (*fmimewrite)(struct soap*, void*, const char*, size_t); +#endif + SOAP_SOCKET master; + SOAP_SOCKET socket; +#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) + std::ostream *os; + std::istream *is; +#else + void *os; /* preserve struct size */ + void *is; /* preserve struct size */ +#endif +#ifndef UNDER_CE + int sendfd; + int recvfd; +#else + FILE *sendfd; + FILE *recvfd; +#endif + size_t bufidx; /* index in soap.buf[] */ + size_t buflen; /* length of soap.buf[] content */ + soap_wchar ahead; /* parser lookahead */ + short cdata; /* CDATA parser state */ + short body; /* parsed XML element has a body or not */ + unsigned int level; /* XML nesting level */ + size_t count; /* message length counter */ + size_t length; /* message length as set by HTTP header */ + char *labbuf; /* look-aside buffer */ + size_t lablen; /* look-aside buffer allocated length */ + size_t labidx; /* look-aside buffer index to available part */ + char buf[SOAP_BUFLEN];/* send and receive buffer */ + char msgbuf[1024]; /* in/out buffer for HTTP/MIME headers >=1024 bytes */ + char tmpbuf[1024]; /* in/out buffer for HTTP/MIME headers, simpleType values, element and attribute tag names, and DIME must be >=1024 bytes */ + char tag[SOAP_TAGLEN]; + char id[SOAP_TAGLEN]; + char href[SOAP_TAGLEN]; + char type[SOAP_TAGLEN]; + char arrayType[SOAP_TAGLEN]; + char arraySize[SOAP_TAGLEN]; + char arrayOffset[SOAP_TAGLEN]; + short other; + short position; + int positions[SOAP_MAXDIMS]; + short root; + struct soap_attribute *attributes; /* attribute list */ + short encoding; /* when set, output encodingStyle */ + short mustUnderstand; /* a mustUnderstand element was parsed or is output */ + short null; /* parsed XML is xsi:nil */ + short ns; /* when not set, output full xmlns bindings */ + short part; /* parsing state */ + short alloced; + short peeked; + size_t chunksize; + size_t chunkbuflen; + char endpoint[SOAP_TAGLEN]; + char path[SOAP_TAGLEN]; + char host[SOAP_TAGLEN]; + char *action; + char *authrealm; /* HTTP authentication realm */ + char *prolog; /* XML declaration prolog */ + unsigned long ip; /* IP number */ + int port; /* port number */ + short keep_alive; /* connection should be kept open */ + short tcp_keep_alive; /* enable SO_KEEPALIVE */ + unsigned int tcp_keep_idle; /* set TCP_KEEPIDLE */ + unsigned int tcp_keep_intvl; /* set TCP_KEEPINTVL */ + unsigned int tcp_keep_cnt; /* set TCP_KEEPCNT */ + unsigned int max_keep_alive; /* maximum keep-alive session (default=100) */ + const char *proxy_http_version;/* HTTP version of proxy "1.0" or "1.1" */ + const char *proxy_host; /* Proxy Server host name */ + int proxy_port; /* Proxy Server port (default = 8080) */ + const char *proxy_userid; /* Proxy Authorization user name */ + const char *proxy_passwd; /* Proxy Authorization password */ + const char *proxy_from; /* X-Forwarding-For header returned by proxy */ + int status; /* -1 when request, else error code to be returned by server */ + int error; + int errmode; + int errnum; +#ifndef WITH_LEANER + struct soap_dom_element *dom; + struct soap_dime dime; + struct soap_mime mime; + struct soap_xlist *xlist; +#endif +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) + const char *logfile[SOAP_MAXLOGS]; + FILE *fdebug[SOAP_MAXLOGS]; + struct soap_mlist *mht[SOAP_PTRHASH]; +#endif +#ifndef WITH_LEAN + const char *wsuid; /* space-separated string of element tags */ + const char *c14nexclude; /* space-separated string of prefixes */ + struct soap_cookie *cookies; + const char *cookie_domain; + const char *cookie_path; + int cookie_max; +#endif +#ifndef WITH_NOIO + int ipv6_multicast_if; /* always include this to keep the soap struct size the same in v4 and v6 */ + char* ipv4_multicast_if; /* always include this to keep the soap struct size the same in v4 and v6 */ + int ipv4_multicast_ttl; /* multicast scope */ +#ifdef WITH_IPV6 + struct sockaddr_storage peer; /* IPv6: set by soap_accept and by UDP recv */ +#else + struct sockaddr_in peer; /* IPv4: set by soap_connect/soap_accept and by UDP recv */ +#endif +#endif + size_t peerlen; +#if defined(WITH_OPENSSL) /* OpenSSL */ + int (*fsslauth)(struct soap*); + int (*fsslverify)(int, X509_STORE_CTX*); + BIO *bio; + SSL *ssl; + SSL_CTX *ctx; + SSL_SESSION *session; + const char *dhfile; + const char *randfile; +#elif defined(WITH_GNUTLS) /* GNUTLS */ + int (*fsslauth)(struct soap*); + void *fsslverify; + gnutls_certificate_credentials_t xcred; /* cert pointer */ + gnutls_anon_client_credentials_t acred; /* anon pointer */ + gnutls_priority_t cache; /* priority cache pointer */ + gnutls_session_t session; /* session pointer */ + gnutls_dh_params_t dh_params; + gnutls_rsa_params_t rsa_params; +#else /* No SSL/TLS */ + void *fsslauth; /* dummy members, to preserve struct size */ + void *fsslverify; + void *bio; + void *ssl; + void *ctx; + void *session; + void *dh_params; + void *rsa_params; +#endif + unsigned short ssl_flags; + const char *keyfile; + const char *password; + const char *cafile; + const char *capath; + const char *crlfile; + char session_host[SOAP_TAGLEN]; + int session_port; +#ifdef WITH_C_LOCALE + locale_t c_locale; /* set to C locale by default */ +#else + void *c_locale; +#endif +#ifdef WITH_ZLIB + z_stream *d_stream; /* decompression stream */ + uLong z_crc; /* internal gzip crc */ +#else + void *d_stream; /* dummy members, to preserve struct size */ + soap_int32 z_crc; +#endif + const char *z_dict; /* support for zlib static dictionaries */ + unsigned int z_dict_len; + short zlib_state; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_INFLATE */ + short zlib_in; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + short zlib_out; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + char *z_buf; /* buffer */ + size_t z_buflen; + unsigned short z_level; /* compression level to be used (0=none, 1=fast to 9=best) */ + float z_ratio_in; /* detected compression ratio compressed_length/length of inbound message */ + float z_ratio_out; /* detected compression ratio compressed_length/length of outbound message */ +#ifdef WMW_RPM_IO /* VxWorks */ + void *rpmreqid; +#endif +#ifdef __cplusplus + soap(); + soap(soap_mode); + soap(soap_mode, soap_mode); + soap(const struct soap&); + virtual ~soap(); +#else + void (*dummy)(void); +#endif +}; + +struct soap_code_map +{ long code; + const char *string; +}; + +/* forwarding list */ +struct soap_flist +{ struct soap_flist *next; + int type; + void *ptr; + unsigned int level; + size_t len; + void (*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t); +}; + +/* id-ref forwarding list */ +struct soap_ilist +{ struct soap_ilist *next; + int type; + size_t size; + void *link; + void *copy; + struct soap_flist *flist; + void *ptr; + unsigned int level; + char id[1]; /* the actual id string value flows into the allocated region below this struct */ +}; + +struct soap_plugin +{ struct soap_plugin *next; + const char *id; + void *data; + int (*fcopy)(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src); + void (*fdelete)(struct soap *soap, struct soap_plugin *p); /* should delete fields of plugin only and not free(p) */ +}; + +#ifndef WITH_NONAMESPACES +extern SOAP_NMAC struct Namespace namespaces[]; +#endif + +#ifndef WITH_LEAN +# define soap_get0(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx]) +# define soap_get1(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx++]) +#else +soap_wchar soap_get0(struct soap*); +soap_wchar soap_get1(struct soap*); +#endif + +#define soap_revget1(soap) ((soap)->bufidx--) +#define soap_unget(soap, c) ((soap)->ahead = c) +#define soap_register_plugin(soap, plugin) soap_register_plugin_arg(soap, plugin, NULL) +#define soap_imode(soap, n) ((soap)->mode = (soap)->imode = (n)) +#define soap_set_imode(soap, n) ((soap)->imode |= (n)) +#define soap_clr_imode(soap, n) ((soap)->imode &= ~(n)) +#define soap_omode(soap, n) ((soap)->mode = (soap)->omode = (n)) +#define soap_set_omode(soap, n) ((soap)->omode |= (n)) +#define soap_clr_omode(soap, n) ((soap)->omode &= ~(n)) +#define soap_set_mode(soap, n) ((soap)->imode |= (n), (soap)->omode |= (n)) +#define soap_clr_mode(soap, n) ((soap)->imode &= ~(n), (soap)->omode &= ~(n)) +#define soap_destroy(soap) soap_delete((soap), NULL) + +#ifdef HAVE_STRRCHR +# define soap_strrchr(s, t) strrchr(s, t) +#else + SOAP_FMAC1 char* SOAP_FMAC2 soap_strrchr(const char *s, int t); +#endif + +#ifdef HAVE_STRTOL +# define soap_strtol(s, t, b) strtol(s, t, b) +#else + SOAP_FMAC1 long SOAP_FMAC2 soap_strtol(const char *s, char **t, int b); +#endif + +#ifdef HAVE_STRTOUL +# define soap_strtoul(s, t, b) strtoul(s, t, b) +#else + SOAP_FMAC1 unsigned long SOAP_FMAC2 soap_strtoul(const char *s, char **t, int b); +#endif + +#if defined(WITH_OPENSSL) +# define soap_random soap_rand() +SOAP_FMAC1 int SOAP_FMAC2 soap_rand(void); +#elif defined(HAVE_RANDOM) +# define soap_random (int)random() +#else +# define soap_random rand() +#endif + +#ifdef WITH_NOIDREF +# define soap_embedded(s, p, t) (0) +# define soap_id_lookup(s, i, p, t, n, k) (p) +# define soap_id_forward(s, h, p, len, st, tt, n, k, fc) (p) +# define soap_reference(s, a, t) (1) +# define soap_array_reference(s, p, a, n, t) (1) +# define soap_embed(s, p, a, n, t, pp) (0) +# define soap_embedded_id(s, i, p, t) (i) +# define soap_is_embedded(s, p) (0) +# define soap_is_single(s, p) (1) +# define soap_lookup_type(s, i) (0) +# define soap_getindependent(s) (0) +# define soap_putindependent(s) (0) +# define soap_getelement(s, n) (n) +# define soap_putelement(s, p, t, i, n) (0) +# define soap_markelement(s, p, n) (0) +#endif + +SOAP_FMAC1 void SOAP_FMAC2 soap_header(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_fault(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultsubcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultstring(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultdetail(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializeheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getheader(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializefault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putfault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getfault(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_ssl_init(void); +SOAP_FMAC1 int SOAP_FMAC2 soap_poll(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect_command(struct soap*, int, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect(struct soap*, const char*, const char*); +SOAP_FMAC1 SOAP_SOCKET SOAP_FMAC2 soap_bind(struct soap*, const char*, int, int); +SOAP_FMAC1 SOAP_SOCKET SOAP_FMAC2 soap_accept(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_accept(struct soap*); +SOAP_FMAC1 const char * SOAP_FMAC2 soap_ssl_error(struct soap*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_server_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_client_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_puthttphdr(struct soap*, int status, size_t count); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_get_header_attribute(struct soap*, const char*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_key(char*, size_t, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_val(char*, size_t, const char*); + +SOAP_FMAC1 size_t SOAP_FMAC2 soap_hash(const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_endpoint(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_get(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getchar(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_tag_cmp(const char*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault_subcode(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault_subcode(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_sender_error(struct soap*, const char*, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_receiver_error(struct soap*, const char*, const char*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_raw(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send2(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send3(struct soap*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_pututf8(struct soap*, unsigned long); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getutf8(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_putbase64(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_getbase64(struct soap*, int*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_puthex(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_gethex(struct soap*, int*); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_xop_forward(struct soap*, unsigned char**, int*, char**, char**, char**); +SOAP_FMAC1 int SOAP_FMAC2 soap_dime_forward(struct soap*, unsigned char**, int*, char**, char**, char**); +#endif + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup_id(struct soap*, void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup(struct soap*, const void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_enter(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_pointer_lookup(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_lookup(struct soap*, const char*); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_enter(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_resolve(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_embedded(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_reference(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_reference(struct soap*, const void *p, const struct soap_array *a, int n, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_embedded_id(struct soap*, int id, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_embedded(struct soap*, struct soap_plist*); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_single(struct soap*, struct soap_plist*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_embedded(struct soap*, struct soap_plist*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_send(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_send(struct soap*); + +SOAP_FMAC1 const struct soap_code_map* SOAP_FMAC2 soap_code(const struct soap_code_map*, const char*); +SOAP_FMAC1 long SOAP_FMAC2 soap_code_int(const struct soap_code_map*, const char*, long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_code_str(const struct soap_code_map*, long); +SOAP_FMAC1 long SOAP_FMAC2 soap_code_bits(const struct soap_code_map*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_code_list(struct soap*, const struct soap_code_map*, long); + +SOAP_FMAC1 int SOAP_FMAC2 soap_getline(struct soap*, char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_recv(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_malloc(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_dealloc(struct soap*, void*); +SOAP_FMAC1 struct soap_clist * SOAP_FMAC2 soap_link(struct soap*, void*, int, int, int (*fdelete)(struct soap_clist*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_unlink(struct soap*, const void*); +SOAP_FMAC1 void SOAP_FMAC2 soap_free_temp(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_del(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_track_malloc(struct soap*, const char*, int, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_track_free(struct soap*, const char*, int, void*); + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_lookup_type(struct soap*, const char *id); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_lookup(struct soap*, const char *id, void **p, int t, size_t n, unsigned int k); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_forward(struct soap*, const char *id, void *p, size_t len, int st, int tt, size_t n, unsigned int k, void(*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t)); +#endif +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_enter(struct soap*, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t, const void *q, size_t n); + +SOAP_FMAC1 int SOAP_FMAC2 soap_size(const int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getoffsets(const char *, const int *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsize(const char *, const char *, int *); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsizes(const char *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getposition(const char *, int *); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsize(struct soap*, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizesoffsets(struct soap*, const char *, const int *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizes(struct soap*, const char *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffset(struct soap*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffsets(struct soap*, const int *, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_closesock(struct soap*); + +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new(void); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new1(soap_mode); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new2(soap_mode, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_free(struct soap*); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy(const struct soap*); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy_context(struct soap*, const struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_copy_stream(struct soap*, struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_free_stream(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init1(struct soap*, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_init2(struct soap*, soap_mode, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_done(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_cleanup(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_begin(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_end(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_delete(struct soap*, void*); +SOAP_FMAC1 void SOAP_FMAC2 soap_delegate_deletion(struct soap*, struct soap*); + +/* API functions available with DEBUG or SOAP_DEBUG defined: */ +SOAP_FMAC1 void SOAP_FMAC2 soap_set_recv_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_sent_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_test_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_close_logfiles(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_open_logfile(struct soap*, int); +/* */ + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_value(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_tag(struct soap*, const char*, const char *); +SOAP_FMAC1 int SOAP_FMAC2 soap_match_array(struct soap*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element(struct soap*, const char*, int, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_out(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_begin_out(struct soap*, const char *tag, int id, const char *type, const char *offset); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_ref(struct soap*, const char *tag, int id, int href); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_href(struct soap*, const char *tag, int id, const char *ref, const char *val); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_null(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_nil(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_id(struct soap*, const char *tag, int id, const void *p, const struct soap_array *a, int d, const char *type, int n); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_result(struct soap*, const char *tag); +SOAP_FMAC1 void SOAP_FMAC2 soap_check_result(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_out(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_start_end_out(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_attribute(struct soap*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_in(struct soap*, const char *tag, int nillable, const char *type); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_in(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_peek_element(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_retry(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_revert(struct soap*); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_strdup(struct soap*, const char*); +SOAP_FMAC1 wchar_t* SOAP_FMAC2 soap_wstrdup(struct soap*, const wchar_t*); +SOAP_FMAC1 const char * SOAP_FMAC2 soap_tagsearch(const char *big, const char *little); + +SOAP_FMAC1 int SOAP_FMAC2 soap_string_out(struct soap*, const char *s, int flag); +SOAP_FMAC1 char* SOAP_FMAC2 soap_string_in(struct soap*, int, long, long); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_wstring_out(struct soap*, const wchar_t *s, int flag); +SOAP_FMAC1 wchar_t* SOAP_FMAC2 soap_wstring_in(struct soap*, int, long, long); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_namespace(struct soap*, const char *, const char*, size_t n1, size_t n2); + +SOAP_FMAC1 int SOAP_FMAC2 soap_set_namespaces(struct soap*, const struct Namespace*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_local_namespaces(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_namespace(struct soap*); +SOAP_FMAC1 struct soap_nlist* SOAP_FMAC2 soap_push_namespace(struct soap*, const char *,const char *); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_current_namespace(struct soap *soap, const char *tag); + +SOAP_FMAC1 struct soap_nlist* SOAP_FMAC2 soap_lookup_ns(struct soap *soap, const char *tag, size_t n); + +SOAP_FMAC1 int SOAP_FMAC2 soap_store_lab(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_append_lab(struct soap*, const char*, size_t); + +SOAP_FMAC1 struct soap_blist* SOAP_FMAC2 soap_new_block(struct soap*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_push_block(struct soap*, struct soap_blist*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_block(struct soap*, struct soap_blist*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_size_block(struct soap*, struct soap_blist*, size_t); +SOAP_FMAC1 char* SOAP_FMAC2 soap_first_block(struct soap*, struct soap_blist*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_next_block(struct soap*, struct soap_blist*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_block_size(struct soap*, struct soap_blist*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_save_block(struct soap*, struct soap_blist*, char*, int); +SOAP_FMAC1 void SOAP_FMAC2 soap_end_block(struct soap*, struct soap_blist*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_out(struct soap*); +SOAP_FMAC1 int soap_envelope_end_out(struct soap*); + +SOAP_FMAC1 char * SOAP_FMAC2 soap_get_http_body(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_out(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_header(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_response(struct soap*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_empty_response(struct soap*, int status); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_empty_response(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap*, int check); + +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault(struct soap*, FILE*); +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault_location(struct soap*, FILE*); +# ifndef WITH_LEAN +# ifdef __cplusplus +SOAP_FMAC1 void SOAP_FMAC2 soap_stream_fault(struct soap*, std::ostream&); +# endif +SOAP_FMAC1 char* SOAP_FMAC2 soap_sprint_fault(struct soap*, char*, size_t); +# endif +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_s2byte(struct soap*, const char*, char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2short(struct soap*, const char*, short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2int(struct soap*, const char*, int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2long(struct soap*, const char*, long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2LONG64(struct soap*, const char*, LONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2float(struct soap*, const char*, float*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2double(struct soap*, const char*, double*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedByte(struct soap*, const char*, unsigned char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedShort(struct soap*, const char*, unsigned short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedInt(struct soap*, const char*, unsigned int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedLong(struct soap*, const char*, unsigned long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2ULONG64(struct soap*, const char*, ULONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2string(struct soap*, const char*, char**, long minlen, long maxlen); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2QName(struct soap*, const char*, char**, long minlen, long maxlen); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_s2wchar(struct soap*, const char*, wchar_t**, long minlen, long maxlen); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2dateTime(struct soap*, const char*, time_t*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2base64(struct soap*, const unsigned char*, char*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2hex(struct soap*, const unsigned char*, char*, int); +#endif + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_byte2s(struct soap*, char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_short2s(struct soap*, short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_int2s(struct soap*, int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_long2s(struct soap*, long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_LONG642s(struct soap*, LONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_float2s(struct soap*, float); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_double2s(struct soap*, double); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedByte2s(struct soap*, unsigned char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedShort2s(struct soap*, unsigned short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedInt2s(struct soap*, unsigned int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedLong2s(struct soap*, unsigned long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_ULONG642s(struct soap*, ULONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_QName2s(struct soap*, const char*); + +#ifndef WITH_LEAN +SOAP_FMAC1 const char* SOAP_FMAC2 soap_wchar2s(struct soap*, const wchar_t*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_dateTime2s(struct soap*, time_t); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_base642s(struct soap*, const char*, char*, size_t, int*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_hex2s(struct soap*, const char*, char*, size_t, int*); +#endif + + +SOAP_FMAC1 int* SOAP_FMAC2 soap_inint(struct soap*, const char *tag, int *p, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_inbyte(struct soap*, const char *tag, char *p, const char *, int); +SOAP_FMAC1 long* SOAP_FMAC2 soap_inlong(struct soap*, const char *tag, long *p, const char *, int); +SOAP_FMAC1 LONG64* SOAP_FMAC2 soap_inLONG64(struct soap*, const char *tag, LONG64 *p, const char *, int); +SOAP_FMAC1 short* SOAP_FMAC2 soap_inshort(struct soap*, const char *tag, short *p, const char *, int); +SOAP_FMAC1 float* SOAP_FMAC2 soap_infloat(struct soap*, const char *tag, float *p, const char *, int); +SOAP_FMAC1 double* SOAP_FMAC2 soap_indouble(struct soap*, const char *tag, double *p, const char *, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_inunsignedByte(struct soap*, const char *tag, unsigned char *p, const char *, int); +SOAP_FMAC1 unsigned short* SOAP_FMAC2 soap_inunsignedShort(struct soap*, const char *tag, unsigned short *p, const char *, int); +SOAP_FMAC1 unsigned int* SOAP_FMAC2 soap_inunsignedInt(struct soap*, const char *tag, unsigned int *p, const char *, int); +SOAP_FMAC1 unsigned long* SOAP_FMAC2 soap_inunsignedLong(struct soap*, const char *tag, unsigned long *p, const char *, int); +SOAP_FMAC1 ULONG64* SOAP_FMAC2 soap_inULONG64(struct soap*, const char *tag, ULONG64 *p, const char *, int); +SOAP_FMAC1 char** SOAP_FMAC2 soap_instring(struct soap*, const char *tag, char **p, const char *, int, int, long, long); +SOAP_FMAC1 char** SOAP_FMAC2 soap_inliteral(struct soap*, const char *tag, char **p); + +#ifndef WITH_LEAN +SOAP_FMAC1 time_t* SOAP_FMAC2 soap_indateTime(struct soap*, const char *tag, time_t *p, const char *, int); +SOAP_FMAC1 time_t SOAP_FMAC2 soap_timegm(struct tm*); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwstring(struct soap*, const char *tag, wchar_t **p, const char *, int, long, long); +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwliteral(struct soap*, const char *tag, wchar_t **p); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_outbyte(struct soap*, const char *tag, int id, const char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outshort(struct soap*, const char *tag, int id, const short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outint(struct soap*, const char *tag, int id, const int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outlong(struct soap*, const char *tag, int id, const long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outLONG64(struct soap*, const char *tag, int id, const LONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outfloat(struct soap*, const char *tag, int id, const float *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outdouble(struct soap*, const char *tag, int id, const double *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedByte(struct soap*, const char *tag, int id, const unsigned char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedShort(struct soap*, const char *tag, int id, const unsigned short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedInt(struct soap*, const char *tag, int id, const unsigned int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedLong(struct soap*, const char *tag, int id, const unsigned long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outULONG64(struct soap*, const char *tag, int id, const ULONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outstring(struct soap*, const char *tag, int id, char *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outliteral(struct soap*, const char *tag, char *const*p, const char *type); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_outdateTime(struct soap*, const char *tag, int id, const time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_outwstring(struct soap*, const char *tag, int id, wchar_t *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outwliteral(struct soap*, const char *tag, wchar_t *const*p, const char *type); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_attachment(struct soap *, const char*, int, const void*, const struct soap_array*, const char*, const char*, const char*, int, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_move(struct soap*, long); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_tell(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_dime_option(struct soap*, unsigned short, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmimehdr(struct soap*, struct soap_multipart*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_mime(struct soap*, const char *boundary, const char *start); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_mime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_dime_attachment(struct soap*, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_mime_attachment(struct soap*, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description); +SOAP_FMAC1 void SOAP_FMAC2 soap_post_check_mime_attachments(struct soap *soap); +SOAP_FMAC1 int SOAP_FMAC2 soap_check_mime_attachments(struct soap *soap); +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_get_mime_attachment(struct soap *soap, void *handle); +SOAP_FMAC1 int SOAP_FMAC2 soap_match_cid(struct soap*, const char*, const char*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_register_plugin_arg(struct soap*, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_lookup_plugin(struct soap*, const char*); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_attr_value(struct soap *soap, const char *name, int flag); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_attr(struct soap *soap, const char *name, const char *value, int flag); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_attr(struct soap *soap); + +#ifdef WITH_COOKIES +SOAP_FMAC1 void SOAP_FMAC2 soap_getcookies(struct soap *soap, const char *val); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_encode_cookie(const char*, char*, size_t); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_set_cookie(struct soap*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_env_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern time_t SOAP_FMAC2 soap_cookie_expire(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_expire(struct soap*, const char*, long, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_clr_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_clr_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_getenv_cookies(struct soap*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_copy_cookies(struct soap*, const struct soap*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_free_cookies(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putsetcookies(struct soap *soap); +SOAP_FMAC1 int SOAP_FMAC2 soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* STDSOAP_H */ diff --git a/ext/CrashServer/external/zlib123/README b/ext/CrashServer/external/zlib123/README new file mode 100644 index 000000000..80f71ae85 --- /dev/null +++ b/ext/CrashServer/external/zlib123/README @@ -0,0 +1,125 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.3 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install". For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.3 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be + installed before testing (do "make install" before "make test"), since the + library location is specified in the library. + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/ext/CrashServer/external/zlib123/adler32.c b/ext/CrashServer/external/zlib123/adler32.c new file mode 100644 index 000000000..f201d6701 --- /dev/null +++ b/ext/CrashServer/external/zlib123/adler32.c @@ -0,0 +1,149 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/ext/CrashServer/external/zlib123/compress.c b/ext/CrashServer/external/zlib123/compress.c new file mode 100644 index 000000000..d37e84f5e --- /dev/null +++ b/ext/CrashServer/external/zlib123/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/crypt.h b/ext/CrashServer/external/zlib123/contrib/minizip/crypt.h new file mode 100644 index 000000000..f14a628b4 --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/crypt.h @@ -0,0 +1,132 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) + const char *passwd; /* password string */ + unsigned char *buf; /* where to write header */ + int bufSize; + unsigned long* pkeys; + const unsigned long* pcrc_32_tab; + unsigned long crcForCrypting; +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/ioapi.c b/ext/CrashServer/external/zlib123/contrib/minizip/ioapi.c new file mode 100644 index 000000000..7f20c182f --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/ioapi.c @@ -0,0 +1,177 @@ +/* ioapi.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include +#include +#include + +#include "zlib.h" +#include "ioapi.h" + + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func OF(( + voidpf opaque, + const char* filename, + int mode)); + +uLong ZCALLBACK fread_file_func OF(( + voidpf opaque, + voidpf stream, + void* buf, + uLong size)); + +uLong ZCALLBACK fwrite_file_func OF(( + voidpf opaque, + voidpf stream, + const void* buf, + uLong size)); + +long ZCALLBACK ftell_file_func OF(( + voidpf opaque, + voidpf stream)); + +long ZCALLBACK fseek_file_func OF(( + voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK fclose_file_func OF(( + voidpf opaque, + voidpf stream)); + +int ZCALLBACK ferror_file_func OF(( + voidpf opaque, + voidpf stream)); + + +voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) + voidpf opaque; + const char* filename; + int mode; +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + + +uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + + +uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + const void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +long ZCALLBACK ftell_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + +long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) + voidpf opaque; + voidpf stream; + uLong offset; + int origin; +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + fseek((FILE *)stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK fclose_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +int ZCALLBACK ferror_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/ioapi.h b/ext/CrashServer/external/zlib123/contrib/minizip/ioapi.h new file mode 100644 index 000000000..e73a3b2bd --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/ioapi.h @@ -0,0 +1,75 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#ifndef _ZLIBIOAPI_H +#define _ZLIBIOAPI_H + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + +#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + + + +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) +#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) +#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) +#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) +#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/iowin32.c b/ext/CrashServer/external/zlib123/contrib/minizip/iowin32.c new file mode 100644 index 000000000..694bc033b --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/iowin32.c @@ -0,0 +1,270 @@ +/* iowin32.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + This IO API version uses the Win32 API (for Microsoft Windows) + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include + +#include "zlib.h" +#include "ioapi.h" +#include "iowin32.h" + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE (0xFFFFFFFF) +#endif + +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +voidpf ZCALLBACK win32_open_file_func OF(( + voidpf opaque, + const char* filename, + int mode)); + +uLong ZCALLBACK win32_read_file_func OF(( + voidpf opaque, + voidpf stream, + void* buf, + uLong size)); + +uLong ZCALLBACK win32_write_file_func OF(( + voidpf opaque, + voidpf stream, + const void* buf, + uLong size)); + +long ZCALLBACK win32_tell_file_func OF(( + voidpf opaque, + voidpf stream)); + +long ZCALLBACK win32_seek_file_func OF(( + voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK win32_close_file_func OF(( + voidpf opaque, + voidpf stream)); + +int ZCALLBACK win32_error_file_func OF(( + voidpf opaque, + voidpf stream)); + +typedef struct +{ + HANDLE hf; + int error; +} WIN32FILE_IOWIN; + +voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode) + voidpf opaque; + const char* filename; + int mode; +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = 0; + voidpf ret=NULL; + + dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0; + + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + { + dwDesiredAccess = GENERIC_READ; + dwCreationDisposition = OPEN_EXISTING; + dwShareMode = FILE_SHARE_READ; + } + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + { + dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + dwCreationDisposition = OPEN_EXISTING; + } + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + { + dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + dwCreationDisposition = CREATE_ALWAYS; + } + + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, + dwCreationDisposition, dwFlagsAndAttributes, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + hFile = NULL; + + if (hFile != NULL) + { + WIN32FILE_IOWIN w32fiow; + w32fiow.hf = hFile; + w32fiow.error = 0; + ret = malloc(sizeof(WIN32FILE_IOWIN)); + if (ret==NULL) + CloseHandle(hFile); + else *((WIN32FILE_IOWIN*)ret) = w32fiow; + } + return ret; +} + + +uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + void* buf; + uLong size; +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + if (!ReadFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + + return ret; +} + + +uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + const void* buf; + uLong size; +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile !=NULL) + if (!WriteFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + + return ret; +} + +long ZCALLBACK win32_tell_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + long ret=-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=(long)dwSet; + } + return ret; +} + +long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin) + voidpf opaque; + voidpf stream; + uLong offset; + int origin; +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + + long ret=-1; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile != NULL) + { + DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +int ZCALLBACK win32_close_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret=-1; + + if (stream!=NULL) + { + HANDLE hFile; + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + CloseHandle(hFile); + ret=0; + } + free(stream); + } + return ret; +} + +int ZCALLBACK win32_error_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret=-1; + if (stream!=NULL) + { + ret = ((WIN32FILE_IOWIN*)stream) -> error; + } + return ret; +} + +void fill_win32_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = win32_open_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell_file = win32_tell_file_func; + pzlib_filefunc_def->zseek_file = win32_seek_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque=NULL; +} diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/iowin32.h b/ext/CrashServer/external/zlib123/contrib/minizip/iowin32.h new file mode 100644 index 000000000..e9c5f8b90 --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/iowin32.h @@ -0,0 +1,21 @@ +/* iowin32.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + This IO API version uses the Win32 API (for Microsoft Windows) + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +#ifdef __cplusplus +} +#endif diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/mztools.c b/ext/CrashServer/external/zlib123/contrib/minizip/mztools.c new file mode 100644 index 000000000..5fecc4ee2 --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/mztools.c @@ -0,0 +1,281 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[256]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/unzip.c b/ext/CrashServer/external/zlib123/contrib/minizip/unzip.c new file mode 100644 index 000000000..3a7062980 --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/unzip.c @@ -0,0 +1,1598 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + Read unzip.h for more info +*/ + +/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of +compatibility with older software. The following is from the original crypt.c. Code +woven in by Terry Thorsen 1/2003. +*/ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + int *pi; +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream)); + +local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) + const char *path; + zlib_filefunc_def* pzlib_filefunc_def; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info cur_file_infoSaved; + unz_file_info_internal cur_file_info_internalSaved; + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; // offset in file + uLong num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) + unzFile file; + int* method; + int* level; + int raw; + const char* password; +{ + int err=UNZ_OK; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_DEFLATED) && + (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (file, password) + unzFile file; + const char* password; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) + unzFile file; + int* method; + int* level; + int raw; +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset (file) + unzFile file; +{ + unz_s* s; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT unzSetOffset (file, pos) + unzFile file; + uLong pos; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/unzip.h b/ext/CrashServer/external/zlib123/contrib/minizip/unzip.h new file mode 100644 index 000000000..c3206a058 --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/unzip.h @@ -0,0 +1,354 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/zip.c b/ext/CrashServer/external/zlib123/contrib/minizip/zip.c new file mode 100644 index 000000000..400e2ba37 --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/zip.c @@ -0,0 +1,1219 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.01e, February 12th, 2005 + + 27 Dec 2004 Rolf Kalbermatter + Modification to zipOpen2 to support globalComment retrieval. + + Copyright (C) 1998-2005 Gilles Vollant + + Read zip.h for more info +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] = + " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + uLong pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralheader; /* size of the central header for cur file */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile_info; + +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile_info ci; /* info on the file curretly writing */ + + uLong begin_pos; /* position of the beginning of the zipfile */ + uLong add_position_when_writting_offset; + uLong number_entry; +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif +} zip_internal; + + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(ldi) + linkedlist_datablock_internal* ldi; +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(ll) + linkedlist_data* ll; +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(ll) + linkedlist_data* ll; +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(ll,buf,len) + linkedlist_data* ll; + const void* buf; + uLong len; +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 or 4 (byte, short or long) +*/ + +local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, uLong x, int nbByte)); +local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong x; + int nbByte; +{ + unsigned char buf[4]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); +local void ziplocal_putValue_inmemory (dest, x, nbByte) + void* dest; + uLong x; + int nbByte; +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) + const tm_zip* ptm; + uLong dosDate; +{ + uLong year = (uLong)ptm->tm_year; + if (year>1980) + year-=1980; + else if (year>80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int ziplocal_getByte OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + int *pi; +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int ziplocal_getShort OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int ziplocal_getLong OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong ziplocal_SearchCentralDir OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream)); + +local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + +/************************************************************/ +extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def) + const char *pathname; + int append; + zipcharpc* globalcomment; + zlib_filefunc_def* pzlib_filefunc_def; +{ + zip_internal ziinit; + zip_internal* zi; + int err=ZIP_OK; + + + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&ziinit.z_filefunc); + else + ziinit.z_filefunc = *pzlib_filefunc_def; + + ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) + (ziinit.z_filefunc.opaque, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + zi = (zip_internal*)ALLOC(sizeof(zip_internal)); + if (zi==NULL) + { + ZCLOSE(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory */ + uLong central_pos,uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry; + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong size_comment; + + central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); + if (central_pos==0) + err=ZIP_ERRNO; + + if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* zipfile global comment length */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((central_pos0) + { + ziinit.globalcomment = ALLOC(size_comment+1); + if (ziinit.globalcomment) + { + size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment); + ziinit.globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - + (offset_central_dir+size_central_dir); + ziinit.add_position_when_writting_offset = byte_before_the_zipfile; + + { + uLong size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, + offset_central_dir + byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + uLong read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&ziinit.central_dir,buf_read, + (uLong)read_this); + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + ziinit.begin_pos = byte_before_the_zipfile; + ziinit.number_entry = number_entry_CD; + + if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, + offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen (pathname, append) + const char *pathname; + int append; +{ + return zipOpen2(pathname,append,NULL,NULL); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; + int raw; + int windowBits; + int memLevel; + int strategy; + const char* password; + uLong crcForCrypting; +{ + zip_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; + + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); + } + + zi->ci.flag = 0; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + + size_extrafield_global + size_comment; + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); + + ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); + ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + /* write the local header */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); + + if ((err==ZIP_OK) && (size_filename>0)) + if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + + if ((err==ZIP_OK) && (size_extrafield_local>0)) + if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) + !=size_extrafield_local) + err = ZIP_ERRNO; + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, + Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = 1; + } +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; + int raw; +{ + return zipOpenNewFileInZip3 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; +{ + return zipOpenNewFileInZip2 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0); +} + +local int zipFlushWriteBuffer(zi) + zip_internal* zi; +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, + zi->ci.buffered_data[i],t); +#endif + } + if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) + !=zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + zi->ci.pos_in_buffered_data = 0; + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (file, buf, len) + zipFile file; + const void* buf; + unsigned len; +{ + zip_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.stream.next_in = (void*)buf; + zi->ci.stream.avail_in = len; + zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + for (i=0;ici.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) + zipFile file; + uLong uncompressed_size; + uLong crc32; +{ + zip_internal* zi; + uLong compressed_size; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + err=deflateEnd(&zi->ci.stream); + zi->ci.stream_initialised = 0; + } + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = (uLong)zi->ci.stream.total_in; + } + compressed_size = (uLong)zi->ci.stream.total_out; +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + ziplocal_putValue_inmemory(zi->ci.central_header+20, + compressed_size,4); /*compr size*/ + if (zi->ci.stream.data_type == Z_ASCII) + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + ziplocal_putValue_inmemory(zi->ci.central_header+24, + uncompressed_size,4); /*uncompr size*/ + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, + (uLong)zi->ci.size_centralheader); + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); + if (ZSEEK(zi->z_filefunc,zi->filestream, + zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if (err==ZIP_OK) /* compressed size, unknown */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + + if (ZSEEK(zi->z_filefunc,zi->filestream, + cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (file) + zipFile file; +{ + return zipCloseFileInZipRaw (file,0,0); +} + +extern int ZEXPORT zipClose (file, global_comment) + zipFile file; + const char* global_comment; +{ + zip_internal* zi; + int err = 0; + uLong size_centraldir = 0; + uLong centraldir_pos_inzip; + uInt size_global_comment; + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + if (global_comment==NULL) + size_global_comment = 0; + else + size_global_comment = (uInt)strlen(global_comment); + + centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + if (ZWRITE(zi->z_filefunc,zi->filestream, + ldi->data,ldi->filled_in_this_block) + !=ldi->filled_in_this_block ) + err = ZIP_ERRNO; + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_datablock(zi->central_dir.first_block); + + if (err==ZIP_OK) /* Magic End */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + + if (err==ZIP_OK) /* size of the central directory */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the + starting disk number */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, + (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + + if (err==ZIP_OK) /* zipfile comment length */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if ((err==ZIP_OK) && (size_global_comment>0)) + if (ZWRITE(zi->z_filefunc,zi->filestream, + global_comment,size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + + if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} diff --git a/ext/CrashServer/external/zlib123/contrib/minizip/zip.h b/ext/CrashServer/external/zlib123/contrib/minizip/zip.h new file mode 100644 index 000000000..cd38b670f --- /dev/null +++ b/ext/CrashServer/external/zlib123/contrib/minizip/zip.h @@ -0,0 +1,235 @@ +/* zip.h -- IO for compress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow creates .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + For uncompress .zip file, look at unzip.h + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.html for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _zip_H +#define _zip_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCtypting)); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCtypting : crc of file to compress (needed for crypting) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); +/* + Close the current file in the zipfile, for fiel opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip_H */ diff --git a/ext/CrashServer/external/zlib123/crc32.c b/ext/CrashServer/external/zlib123/crc32.c new file mode 100644 index 000000000..32814c20c --- /dev/null +++ b/ext/CrashServer/external/zlib123/crc32.c @@ -0,0 +1,423 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/ext/CrashServer/external/zlib123/crc32.h b/ext/CrashServer/external/zlib123/crc32.h new file mode 100644 index 000000000..5de49bc97 --- /dev/null +++ b/ext/CrashServer/external/zlib123/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/ext/CrashServer/external/zlib123/deflate.c b/ext/CrashServer/external/zlib123/deflate.c new file mode 100644 index 000000000..529f716b7 --- /dev/null +++ b/ext/CrashServer/external/zlib123/deflate.c @@ -0,0 +1,1736 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/ext/CrashServer/external/zlib123/deflate.h b/ext/CrashServer/external/zlib123/deflate.h new file mode 100644 index 000000000..222c53e04 --- /dev/null +++ b/ext/CrashServer/external/zlib123/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/ext/CrashServer/external/zlib123/gzio.c b/ext/CrashServer/external/zlib123/gzio.c new file mode 100644 index 000000000..5e20a4aa0 --- /dev/null +++ b/ext/CrashServer/external/zlib123/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id$ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/ext/CrashServer/external/zlib123/infback.c b/ext/CrashServer/external/zlib123/infback.c new file mode 100644 index 000000000..1e03e1bab --- /dev/null +++ b/ext/CrashServer/external/zlib123/infback.c @@ -0,0 +1,623 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->write = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + + /* process literal */ + if (this.op == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/ext/CrashServer/external/zlib123/inffast.c b/ext/CrashServer/external/zlib123/inffast.c new file mode 100644 index 000000000..fa31cad90 --- /dev/null +++ b/ext/CrashServer/external/zlib123/inffast.c @@ -0,0 +1,318 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/ext/CrashServer/external/zlib123/inffast.h b/ext/CrashServer/external/zlib123/inffast.h new file mode 100644 index 000000000..614fa7877 --- /dev/null +++ b/ext/CrashServer/external/zlib123/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/ext/CrashServer/external/zlib123/inffixed.h b/ext/CrashServer/external/zlib123/inffixed.h new file mode 100644 index 000000000..423d5c5b5 --- /dev/null +++ b/ext/CrashServer/external/zlib123/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/ext/CrashServer/external/zlib123/inflate.c b/ext/CrashServer/external/zlib123/inflate.c new file mode 100644 index 000000000..33ea90292 --- /dev/null +++ b/ext/CrashServer/external/zlib123/inflate.c @@ -0,0 +1,1368 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/ext/CrashServer/external/zlib123/inflate.h b/ext/CrashServer/external/zlib123/inflate.h new file mode 100644 index 000000000..fbbc87143 --- /dev/null +++ b/ext/CrashServer/external/zlib123/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/ext/CrashServer/external/zlib123/inftrees.c b/ext/CrashServer/external/zlib123/inftrees.c new file mode 100644 index 000000000..38ded81c3 --- /dev/null +++ b/ext/CrashServer/external/zlib123/inftrees.c @@ -0,0 +1,329 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)1; + this.val = (unsigned short)0; + *(*table)++ = this; /* make a table to force an error */ + *(*table)++ = this; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/ext/CrashServer/external/zlib123/inftrees.h b/ext/CrashServer/external/zlib123/inftrees.h new file mode 100644 index 000000000..dc0fd567e --- /dev/null +++ b/ext/CrashServer/external/zlib123/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/ext/CrashServer/external/zlib123/trees.c b/ext/CrashServer/external/zlib123/trees.c new file mode 100644 index 000000000..7a0480286 --- /dev/null +++ b/ext/CrashServer/external/zlib123/trees.c @@ -0,0 +1,1219 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) + deflate_state *s; +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/ext/CrashServer/external/zlib123/trees.h b/ext/CrashServer/external/zlib123/trees.h new file mode 100644 index 000000000..1ca868b84 --- /dev/null +++ b/ext/CrashServer/external/zlib123/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/ext/CrashServer/external/zlib123/uncompr.c b/ext/CrashServer/external/zlib123/uncompr.c new file mode 100644 index 000000000..ad6db0a67 --- /dev/null +++ b/ext/CrashServer/external/zlib123/uncompr.c @@ -0,0 +1,61 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/ext/CrashServer/external/zlib123/zconf.h b/ext/CrashServer/external/zlib123/zconf.h new file mode 100644 index 000000000..e3b0c962e --- /dev/null +++ b/ext/CrashServer/external/zlib123/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/ext/CrashServer/external/zlib123/zlib.h b/ext/CrashServer/external/zlib123/zlib.h new file mode 100644 index 000000000..62d0e4675 --- /dev/null +++ b/ext/CrashServer/external/zlib123/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/ext/CrashServer/external/zlib123/zutil.c b/ext/CrashServer/external/zlib123/zutil.c new file mode 100644 index 000000000..0f4bd7871 --- /dev/null +++ b/ext/CrashServer/external/zlib123/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/ext/CrashServer/external/zlib123/zutil.h b/ext/CrashServer/external/zlib123/zutil.h new file mode 100644 index 000000000..0ba6e0208 --- /dev/null +++ b/ext/CrashServer/external/zlib123/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ -- 2.11.4.GIT

ejU=o@O`0Z>L~d5p!k># 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