summaryrefslogtreecommitdiff
path: root/protocols/MRA/Sdk
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /protocols/MRA/Sdk
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/MRA/Sdk')
-rw-r--r--protocols/MRA/Sdk/Base64.h380
-rw-r--r--protocols/MRA/Sdk/BuffToLowerCase.h98
-rw-r--r--protocols/MRA/Sdk/DebugFunctions.h148
-rw-r--r--protocols/MRA/Sdk/FIFOMT.h133
-rw-r--r--protocols/MRA/Sdk/InterlockedFunctions.h156
-rw-r--r--protocols/MRA/Sdk/InternetTime.h473
-rw-r--r--protocols/MRA/Sdk/ListMT.h358
-rw-r--r--protocols/MRA/Sdk/MemoryCompare.h101
-rw-r--r--protocols/MRA/Sdk/MemoryFind.h80
-rw-r--r--protocols/MRA/Sdk/MemoryFindByte.h97
-rw-r--r--protocols/MRA/Sdk/MemoryReplace.h150
-rw-r--r--protocols/MRA/Sdk/RC4.h103
-rw-r--r--protocols/MRA/Sdk/SHA1.h596
-rw-r--r--protocols/MRA/Sdk/SocketFunctions.h485
-rw-r--r--protocols/MRA/Sdk/StrHexToNum.h634
-rw-r--r--protocols/MRA/Sdk/StrToNum.h447
-rw-r--r--protocols/MRA/Sdk/timefuncs.h131
-rw-r--r--protocols/MRA/Sdk/zconf.h428
-rw-r--r--protocols/MRA/Sdk/zlib.h1357
19 files changed, 6355 insertions, 0 deletions
diff --git a/protocols/MRA/Sdk/Base64.h b/protocols/MRA/Sdk/Base64.h
new file mode 100644
index 0000000000..f371399a06
--- /dev/null
+++ b/protocols/MRA/Sdk/Base64.h
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#if !defined(AFX_BASE64__H__INCLUDED_)
+#define AFX_BASE64__H__INCLUDED_
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+//typedef unsigned char BYTE;
+//
+// BASE64 coding:
+// 214 46 138
+// 11010100 00101110 10001010
+// ! ! !
+// ---------->>> convert 3 8bit to 4 6bit
+// 110101 000010 111010 001010
+// 53 2 58 10
+// this numbers is offset in array coding below...
+//
+ //01234567890123456789012345
+static BYTE *pbtCodingTableBASE64=(BYTE*)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //52...63
+static BYTE btDeCodingTableBASE64[256]={64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64};
+
+
+
+
+__inline void BASE64CopyUnSafe(LPCVOID lpcSource,LPCVOID lpcDestination,SIZE_T dwSize,SIZE_T *pdwCopyedSize)
+{// копируем только б64 символы
+ LPBYTE lpbSource,lpbDestination;
+
+ lpbSource=(LPBYTE)lpcSource;
+ lpbDestination=(LPBYTE)lpcDestination;
+ while(dwSize--)
+ {
+ if ((*lpbSource)>32 && (*lpbSource)<128) (*lpbDestination++)=(*lpbSource);
+ lpbSource++;
+ }
+ if (pdwCopyedSize) (*pdwCopyedSize)=((SIZE_T)lpbDestination-(SIZE_T)lpcDestination);
+}
+
+
+
+__inline DWORD BASE64EncodeUnSafe(LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcDestination,SIZE_T dwDestinationSize,SIZE_T *pdwEncodedSize)
+{// BASE64 кодирование
+ DWORD dwRetErrorCode;
+ SIZE_T dwEncodedSize=((dwSourceSize*4+11)/12*4+1);//(((dwSourceSize+2)/3)*4);
+
+ if ((dwDestinationSize<dwEncodedSize))
+ {// выходной буффер слишком мал
+ dwRetErrorCode=ERROR_INSUFFICIENT_BUFFER;
+ }else{// размер выходного буффера достаточен
+ dwEncodedSize=0;
+ if(lpcSource && lpcDestination && dwSourceSize)
+ {
+#ifdef _WIN64
+ LPBYTE lpbtSource=(LPBYTE)lpcSource,lpbtDestination=(LPBYTE)lpcDestination;
+ SIZE_T i;
+
+ for (i=0;i<dwSourceSize;i+=3)
+ {
+ *(lpbtDestination++)=pbtCodingTableBASE64[(*lpbtSource)>>2]; // c1
+ *(lpbtDestination++)=pbtCodingTableBASE64[(((*lpbtSource)<<4)&060) | ((lpbtSource[1]>>4)&017)]; // c2
+ *(lpbtDestination++)=pbtCodingTableBASE64[((lpbtSource[1]<<2)&074) | ((lpbtSource[2]>>6)&03)]; // c3
+ *(lpbtDestination++)=pbtCodingTableBASE64[lpbtSource[2] & 077]; // c4
+ lpbtSource+=3;
+ }
+
+ // If dwSourceSize was not a multiple of 3, then we have encoded too many characters. Adjust appropriately.
+ if(i==(dwSourceSize+1))
+ {// There were only 2 bytes in that last group
+ lpbtDestination[-1]='=';
+ }else
+ if(i==(dwSourceSize+2))
+ {// There was only 1 byte in that last group
+ lpbtDestination[-1]='=';
+ lpbtDestination[-2]='=';
+ }
+
+ (*lpbtDestination)=0;
+ dwEncodedSize=(lpbtDestination-((LPBYTE)lpcDestination));
+
+#else
+ __asm{
+ push ebx // сохраняем регистр
+ push edi // сохраняем регистр
+ push esi // сохраняем регистр
+
+ mov ebx,pbtCodingTableBASE64// ebx = адрес таблицы перекодировки
+ mov ecx,dwSourceSize // ecx = длинна входного буффера
+ mov edi,lpcDestination // edi = адрес выходного буффера
+ mov esi,lpcSource // esi = указатель на входной буффер
+ cld
+ jmp short read_loop_cmp
+
+ //////////Code function///////////////////////////////////////////
+ // функция кодировки
+ // eax - входящий буффер, используется только 3 байта //in buff, 3 byte used
+ // eax - выходящий буффер, используется 4 байта //out buff, 4 byte used
+ code_func:
+ // третья версия функции разложения,
+ // меняем местами два крайних байта
+ bswap eax
+ rol eax,6
+ shl al,2
+ ror eax,10
+ shr ax,2
+ shr al,2
+ xlat
+ rol eax,8
+ xlat
+ rol eax,8
+ xlat
+ rol eax,8
+ xlat
+ rol eax,8
+ bswap eax// 188-235
+ ret
+ //////////////////////////////////////////////////////////////////
+
+ /////////////Read & converting cycle//////////////////////////////
+ read_loop:
+ lodsd // читаем 4 байта
+ dec esi // используем только 3
+ and eax,0x00FFFFFF
+ //====================================================
+ // третья версия функции разложения,
+ // меняем местами два крайних байта
+ bswap eax
+ rol eax,6
+ shl al,2
+ ror eax,10
+ shr ax,2
+ shr al,2
+ xlat
+ rol eax,8
+ xlat
+ rol eax,8
+ xlat
+ rol eax,8
+ xlat
+ rol eax,8
+ bswap eax
+ //====================================================
+ stosd
+ sub ecx,3
+
+ read_loop_cmp:
+ cmp ecx,3 // проверяем, чтобы длинна была как минимум 4 байта
+ jg short read_loop // если длинна 3 и более байт, то продолжаем дальше
+
+ /////////////////////////////////////////////////////////////////
+ xor eax,eax // обнуляем регистр
+ cmp ecx,3 // сравниваем длинну с 3
+ je short tree_byte_tail// если длинна 3 байта, то переходим к функции обрабатывающей остаток такой длинны
+ cmp ecx,2 // сравниваем длинну с 2
+ je short two_byte_tail // если длинна 2 байта, то переходим к функции обрабатывающей остаток такой длинны
+ // иначе, длинна остатка равна 1
+ //////////tail 1 byte////////////////////////////////////////////
+ mov al,byte ptr [esi] // читаем 1 байт
+ call code_func // преобразуем
+ and eax,0x0000FFFF // обнуляем последние два байта
+ or eax,0x3D3D0000 // записываем в последние два байта 61("=")
+ jmp short end_tail_handler //
+
+ //////////tail 2 byte////////////////////////////////////////////
+ two_byte_tail:
+ mov ax,word ptr [esi] // читаем 2 байта
+ call code_func // преобразуем
+ and eax,0x00FFFFFF // обнуляем последний байт
+ or eax,0x3D000000 // записываем в последний байт 61("=")
+ jmp short end_tail_handler //
+
+ //////////tail 3 byte////////////////////////////////////////////
+ tree_byte_tail:
+ lodsw
+ ror eax,16
+ mov al,byte ptr [esi] // читаем 1 байт
+ rol eax,16
+ call code_func // преобразуем
+
+ end_tail_handler:
+ stosd // записываем 4 байта, уже закодированных
+
+ sub edi,lpcDestination // вычисляем колличество байт, записанных в выходной буффер
+ mov dwEncodedSize,edi // записываем колличество байт в возвращаемую переменную
+ pop esi // восстанавливаем содержимое регистра
+ pop edi // восстанавливаем содержимое регистра
+ pop ebx // восстанавливаем содержимое регистра
+ }
+#endif
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+ }
+ if (pdwEncodedSize) (*pdwEncodedSize)=dwEncodedSize;
+
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD BASE64Encode(LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcDestination,SIZE_T dwDestinationSize,SIZE_T *pdwEncodedSize)
+{// BASE64 кодирование
+ DWORD dwRetErrorCode;
+
+ __try
+ {
+ dwRetErrorCode=BASE64EncodeUnSafe(lpcSource,dwSourceSize,lpcDestination,dwDestinationSize,pdwEncodedSize);
+ }__except(EXCEPTION_EXECUTE_HANDLER){
+ dwRetErrorCode=ERROR_INVALID_ADDRESS;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+__inline DWORD BASE64DecodeUnSafe(LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcDestination,SIZE_T dwDestinationSize,SIZE_T *pdwDecodedSize)
+{// BASE64 декодирование
+ DWORD dwRetErrorCode;
+ SIZE_T dwDecodedSize=((dwSourceSize>>2)*3);// ((dwSourceSize/4)*3);
+
+ if ((dwDestinationSize<dwDecodedSize))
+ {// выходной буффер слишком мал
+ dwRetErrorCode=ERROR_INSUFFICIENT_BUFFER;
+ }else{// размер выходного буффера достаточен
+ dwDecodedSize=0;
+ if(lpcSource && lpcDestination)
+ {// буффера в порядке
+ if (dwSourceSize>3)
+ {
+#ifdef _WIN64
+ LPBYTE lpbtSource=(LPBYTE)lpcSource,lpbtDestination=(LPBYTE)lpcDestination;
+
+ for(SIZE_T i=0;i<dwSourceSize;i+=4)
+ {
+ *(lpbtDestination++)=(unsigned char) (btDeCodingTableBASE64[(*lpbtSource)] << 2 | btDeCodingTableBASE64[lpbtSource[1]] >> 4);
+ *(lpbtDestination++)=(unsigned char) (btDeCodingTableBASE64[lpbtSource[1]] << 4 | btDeCodingTableBASE64[lpbtSource[2]] >> 2);
+ *(lpbtDestination++)=(unsigned char) (btDeCodingTableBASE64[lpbtSource[2]] << 6 | btDeCodingTableBASE64[lpbtSource[3]]);
+ lpbtSource+=4;
+ }
+
+ dwDecodedSize=(lpbtDestination-((LPBYTE)lpcDestination));
+ if((*((BYTE*)lpcSource+(dwSourceSize-1)))=='=') dwDecodedSize--;
+ if((*((BYTE*)lpcSource+(dwSourceSize-2)))=='=') dwDecodedSize--;
+
+
+#else
+ __asm{
+ push ebx // сохраняем регистр
+ push edi // сохраняем регистр
+ push esi // сохраняем регистр
+
+ mov ebx,offset btDeCodingTableBASE64// ebx = адрес таблицы перекодировки
+ mov ecx,dwSourceSize // ecx = длинна входного буффера
+ mov edi,lpcDestination // edi = адрес выходного буффера
+ mov esi,lpcSource // esi = указатель на входной буффер
+ cld
+
+ read_loop:
+ lodsd // читаем 4 байта
+ //===============bit conversion====================================
+ // eax - входящий буффер, используется только 4 байта //in buff, 4 byte used
+ // eax - выходящий буффер, используется только 3 байта //out buff, 3 byte used
+ // третья версия функции сложения бит
+ bswap eax
+
+ ror eax,8
+ xlat
+
+ ror eax,8
+ xlat
+
+ ror eax,8
+ xlat
+
+ ror eax,8
+ xlat
+
+ shl al,2
+ shl ax,2
+ rol eax,10
+ shr al,2
+ ror eax,6
+ bswap eax
+ mov edx,eax
+ //234-250
+ //===============================================================
+ stosd
+ dec edi
+ sub ecx,4
+ cmp ecx,3
+ jg short read_loop
+
+ sub edi,lpcDestination // вычисляем колличество байт, записанных в выходной буффер
+ mov dwDecodedSize,edi // записываем колличество байт в возвращаемую переменную
+ pop esi // восстанавливаем содержимое регистра
+ pop edi // восстанавливаем содержимое регистра
+ pop ebx // восстанавливаем содержимое регистра
+ }
+
+ if((*((BYTE*)lpcSource+(dwSourceSize-1)))=='=') dwDecodedSize--;
+ if((*((BYTE*)lpcSource+(dwSourceSize-2)))=='=') dwDecodedSize--;
+#endif
+ dwRetErrorCode=NO_ERROR;
+ }else{// во входном буффере слишком мало данных
+ dwRetErrorCode=ERROR_INSUFFICIENT_BUFFER;
+ }
+ }else{
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+ }
+
+ if (pdwDecodedSize) (*pdwDecodedSize)=dwDecodedSize;
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD BASE64Decode(LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcDestination,SIZE_T dwDestinationSize,SIZE_T *pdwDecodedSize)
+{// BASE64 декодирование
+ DWORD dwRetErrorCode;
+
+ __try
+ {
+ dwRetErrorCode=BASE64DecodeUnSafe(lpcSource,dwSourceSize,lpcDestination,dwDestinationSize,pdwDecodedSize);
+ }__except(EXCEPTION_EXECUTE_HANDLER){
+ dwRetErrorCode=ERROR_INVALID_ADDRESS;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD BASE64DecodeFormated(LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcDestination,SIZE_T dwDestinationSize,SIZE_T *pdwDecodedSize)
+{// BASE64 декодирование и игнорирование форматирования
+ DWORD dwRetErrorCode;
+
+ if (dwSourceSize<=dwDestinationSize)
+ {
+ BASE64CopyUnSafe(lpcSource,lpcDestination,dwSourceSize,&dwSourceSize);
+ dwRetErrorCode=BASE64DecodeUnSafe(lpcDestination,dwSourceSize,lpcDestination,dwDestinationSize,pdwDecodedSize);
+ }else{// во входном буффере слишком мало данных
+ dwRetErrorCode=ERROR_INSUFFICIENT_BUFFER;
+ }
+
+return(dwRetErrorCode);
+}
+
+
+
+#endif // !defined(AFX_BASE64__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/BuffToLowerCase.h b/protocols/MRA/Sdk/BuffToLowerCase.h
new file mode 100644
index 0000000000..0cb0eb3cc1
--- /dev/null
+++ b/protocols/MRA/Sdk/BuffToLowerCase.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#if !defined(AFX_BUFFTOLOWERCASE__H__INCLUDED_)
+#define AFX_BUFFTOLOWERCASE__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+__inline BOOL BuffToLowerCase(LPCVOID lpcOutBuff,LPCVOID lpcBuff,SIZE_T dwLen)
+{
+ BOOL bRet=TRUE;
+
+#if defined(_WIN64) || !defined(_WIN32)
+ if (lpcOutBuff && lpcBuff && dwLen)
+ {
+ BYTE bt;
+ LPBYTE lpbtIn=(LPBYTE)lpcBuff,lpbtOut=(LPBYTE)lpcOutBuff;
+
+ for(SIZE_T i=dwLen;i;i--)
+ {
+ bt=(*(lpbtIn++));
+ if (bt>='A' && bt<='Z') bt|=32;
+ (*(lpbtOut++))=bt;
+ }
+ }
+#else
+ __asm
+ {
+ mov ecx,dwLen
+ test ecx,ecx
+ jz short end_func
+
+ push ebx // сохраняем регистр
+ push edi // сохраняем регистр
+ push esi // сохраняем регистр
+ mov esi,lpcBuff
+ mov edi,lpcOutBuff
+ mov bl,'A'
+ mov bh,'Z'
+ mov ah,32
+ cld
+
+ lowcaseloop:
+ lodsb
+ cmp al,bl
+ jl short savebyte
+ cmp al,bh
+ jg short savebyte
+ or al,ah
+
+ savebyte:
+ stosb
+
+ dec ecx
+ jnz short lowcaseloop
+
+ pop esi // восстанавливаем содержимое регистра
+ pop edi // восстанавливаем содержимое регистра
+ pop ebx // восстанавливаем содержимое регистра
+ end_func:
+ }
+#endif
+return(bRet);
+}
+
+
+
+
+#endif // !defined(AFX_BUFFTOLOWERCASE__H__INCLUDED_) \ No newline at end of file
diff --git a/protocols/MRA/Sdk/DebugFunctions.h b/protocols/MRA/Sdk/DebugFunctions.h
new file mode 100644
index 0000000000..6bd9df5b5a
--- /dev/null
+++ b/protocols/MRA/Sdk/DebugFunctions.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2004 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_DEBUG_FUNCTIONS__H__INCLUDED_)
+#define AFX_DEBUG_FUNCTIONS__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef szCRLF
+#define szCRLF TEXT("\r\n")
+#endif
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////DebugPrint////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// DebugBuildPrint(Helo world);
+// Отображение текста в Debug окне во время отладки
+#ifdef _DEBUG
+ #define DebugPrintA(szText) OutputDebugStringA((szText))
+ #define DebugPrintW(szText) OutputDebugStringW((szText))
+ #define DebugPrintCRLFA(szText) OutputDebugStringA((szText));OutputDebugStringA("\r\n")
+ #define DebugPrintCRLFW(szText) OutputDebugStringW((szText));OutputDebugStringW(L"\r\n")
+#else
+ #define DebugPrintA(szText)
+ #define DebugPrintW(szText)
+ #define DebugPrintCRLFA(szText)
+ #define DebugPrintCRLFW(szText)
+#endif //_DEBUG
+
+
+#ifdef UNICODE
+ #define DebugPrint DebugPrintW
+ #define DebugPrintCRLF DebugPrintCRLFW
+#else
+ #define DebugPrint DebugPrintA
+ #define DebugPrintCRLF DebugPrintCRLFA
+#endif
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////DebugBuildPrint///////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// #pragma DebugBuildPrint(Helo world);
+// Отображение сообщений в Build окне во время компиляции
+#ifdef _DEBUG
+ #pragma warning(disable:4081)
+ #define chSTR2(x) #x
+ #define chSTR(x) chSTR2(x)
+ #define DebugBuildPrint(szText) message(__FILE__ "(" chSTR(__LINE__) "): " #szText)
+ #pragma warning(default:4081)
+#else
+ #define DebugBuildPrint(szText)
+#endif //_DEBUG
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////DebugBufferFill///////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// DebugBufferFill(szString,sizeof(szString));
+// Полностью заполняет переданный буффер символом "A", применяется
+// для выходного буффера на входе в функцию.
+#ifdef _DEBUG
+ #define DebugBufferFill(lpBuffer,dwSize) memset(lpBuffer,'A',dwSize)
+#else
+ #define DebugBufferFill(lpBuffer,dwSize)
+#endif //_DEBUG
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////DebugBreak////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// DebugBreak();
+// Точка останова, более удобная альтернатива API
+#if defined(_DEBUG)
+ #if defined(_X86_)
+ #define DebugBreak() _asm{int 3}
+ #else
+ #include <intrin.h>
+ #define DebugBreak() __debugbreak()
+ #endif
+#else
+ #define DebugBreak()
+#endif //_DEBUG
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////DebugBreakIf//////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// DebugBreakIf();
+// Точка останова, более удобная альтернатива API, срабатывает при условии
+#if defined(_DEBUG)
+ #define DebugBreakIf(a) if ((a)) DebugBreak();
+#else
+ #define DebugBreakIf(a)
+#endif //_DEBUG
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+
+
+
+#endif // !defined(AFX_DEBUG_FUNCTIONS__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/FIFOMT.h b/protocols/MRA/Sdk/FIFOMT.h
new file mode 100644
index 0000000000..f0776cba1e
--- /dev/null
+++ b/protocols/MRA/Sdk/FIFOMT.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_FIFO_MT__H__INCLUDED_)
+#define AFX_FIFO_MT__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#include <ListMT.h>
+#include <InterlockedFunctions.h>
+
+
+
+
+
+typedef LIST_MT FIFO_MT, *PFIFO_MT, *LPFIFO_MT;
+typedef PCLIST_MT PCFIFO_MT, LPCFIFO_MT;
+
+typedef LIST_MT_ITEM FIFO_MT_ITEM, *PFIFO_MT_ITEM, *LPFIFO_MT_ITEM;
+typedef PCLIST_MT_ITEM PCFIFO_MT_ITEM, LPCFIFO_MT_ITEM;
+
+typedef LIST_MT_ITERATOR FIFO_MT_ITERATOR, *PFIFO_MT_ITERATOR, *LPFIFO_MT_ITERATOR;
+typedef PCLIST_MT_ITERATOR PCFIFO_MT_ITERATOR, LPCFIFO_MT_ITERATOR;
+
+
+
+
+
+
+#define FifoMTInitialize(pcpmtFifoMT,dwSpinCount) ListMTInitialize(pcpmtFifoMT,dwSpinCount)
+#define FifoMTDestroy(pcpmtFifoMT) ListMTDestroy(pcpmtFifoMT)
+
+
+__inline SIZE_T FifoMTItemPush(PCFIFO_MT pcpmtFifoMT,PCFIFO_MT_ITEM pcffmtiFifoItem,LPVOID lpData)
+{
+ SIZE_T dwRet;
+
+ ListMTLock(pcpmtFifoMT);
+ dwRet=ListMTItemAdd(pcpmtFifoMT,pcffmtiFifoItem,lpData);
+ ListMTUnLock(pcpmtFifoMT);
+
+return(dwRet);
+}
+
+
+__inline DWORD FifoMTItemPop(PCFIFO_MT pcpmtFifoMT,PFIFO_MT_ITEM *ppffmtiFifoItem,LPVOID *plpData)
+{
+ DWORD dwRetErrorCode;
+ PLIST_MT_ITEM plmtiItem;
+
+ ListMTLock(pcpmtFifoMT);
+ if ((dwRetErrorCode=ListMTItemGetFirst(pcpmtFifoMT,&plmtiItem,plpData))==NO_ERROR)
+ {
+ if (ppffmtiFifoItem) (*ppffmtiFifoItem)=plmtiItem;
+ dwRetErrorCode=ListMTItemDelete(pcpmtFifoMT,plmtiItem);
+ }
+ ListMTUnLock(pcpmtFifoMT);
+
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD FifoMTItemGetFirst(PCFIFO_MT pcpmtFifoMT,PFIFO_MT_ITEM *ppffmtiFifoItem,LPVOID *plpData)
+{
+ DWORD dwRetErrorCode;
+
+ ListMTLock(pcpmtFifoMT);
+ dwRetErrorCode=ListMTItemGetFirst(pcpmtFifoMT,ppffmtiFifoItem,plpData);
+ ListMTUnLock(pcpmtFifoMT);
+
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD FifoMTItemGetLast(PCFIFO_MT pcpmtFifoMT,PFIFO_MT_ITEM *ppffmtiFifoItem,LPVOID *plpData)
+{
+ DWORD dwRetErrorCode;
+
+ ListMTLock(pcpmtFifoMT);
+ dwRetErrorCode=ListMTItemGetLast(pcpmtFifoMT,ppffmtiFifoItem,plpData);
+ ListMTUnLock(pcpmtFifoMT);
+
+return(dwRetErrorCode);
+}
+
+
+#define FifoMTGetCount(pcpmtFifoMT) ListMTGetCount(pcpmtFifoMT)
+
+#define FifoMTTryLock(pcpmtFifoMT) ListMTTryLock(pcpmtFifoMT)
+#define FifoMTLock(pcpmtFifoMT) ListMTLock(pcpmtFifoMT)
+#define FifoMTUnLock(pcpmtFifoMT) ListMTUnLock(pcpmtFifoMT)
+
+#define FifoMTItemSwap(pcpmtFifoMT,pcffmtiFifoItem1,pcffmtiFifoItem2) ListMTItemSwap(pcpmtFifoMT,pcffmtiFifoItem1,pcffmtiFifoItem2)
+
+#define FifoMTIteratorMoveFirst(pcpmtFifoMT,pffmtiIterator) ListMTIteratorMoveFirst(pcpmtFifoMT,pffmtiIterator)
+#define FifoMTIteratorMoveLast(pcpmtFifoMT,pffmtiIterator) ListMTIteratorMoveLast(pcpmtFifoMT,pffmtiIterator)
+#define FifoMTIteratorMovePrev(pffmtiIterator) ListMTIteratorMovePrev(pffmtiIterator)
+#define FifoMTIteratorMoveNext(pffmtiIterator) ListMTIteratorMoveNext(pffmtiIterator)
+#define FifoMTIteratorGet(pffmtiIterator,ppffmtiFifoItem,plpData) ListMTIteratorGet(pffmtiIterator,ppffmtiFifoItem,plpData)
+
+
+
+
+#endif // !defined(AFX_FIFO_MT__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/InterlockedFunctions.h b/protocols/MRA/Sdk/InterlockedFunctions.h
new file mode 100644
index 0000000000..742f904944
--- /dev/null
+++ b/protocols/MRA/Sdk/InterlockedFunctions.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_)
+#define AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+
+
+#ifdef InterlockedCompareExchange
+#ifndef InterlockedAnd
+LONG FORCEINLINE InterlockedAnd(LONG volatile *Destination,LONG Value)
+{
+ LONG Old;
+
+ do
+ {
+ Old=*Destination;
+ }while(InterlockedCompareExchange(Destination,(Old&Value),Old)!=Old);
+return(Old);
+}
+#endif //InterlockedAnd
+
+
+#ifndef InterlockedOr
+LONG FORCEINLINE InterlockedOr(LONG volatile *Destination,LONG Value)
+{
+ LONG Old;
+
+ do
+ {
+ Old=*Destination;
+ }while(InterlockedCompareExchange(Destination,(Old|Value),Old)!=Old);
+return(Old);
+}
+#endif //InterlockedOr
+
+
+#ifndef InterlockedXor
+LONG FORCEINLINE InterlockedXor(LONG volatile *Destination,LONG Value)
+{
+ LONG Old;
+
+ do
+ {
+ Old=*Destination;
+ }while(InterlockedCompareExchange(Destination,(Old^Value),Old)!=Old);
+return(Old);
+}
+#endif //InterlockedXor
+#endif //InterlockedCompareExchange
+
+
+
+
+
+#ifdef InterlockedCompareExchange64
+#ifndef InterlockedAnd64
+LONGLONG FORCEINLINE InterlockedAnd64(LONGLONG volatile *Destination,LONGLONG Value)
+{
+ LONGLONG Old;
+
+ do
+ {
+ Old=*Destination;
+ }while(InterlockedCompareExchange64(Destination,(Old&Value),Old)!=Old);
+return(Old);
+}
+#endif //InterlockedAnd64
+
+
+#ifndef InterlockedOr64
+LONGLONG FORCEINLINE InterlockedOr64(LONGLONG volatile *Destination,LONGLONG Value)
+{
+ LONGLONG Old;
+
+ do
+ {
+ Old=*Destination;
+ }while(InterlockedCompareExchange64(Destination,(Old|Value),Old)!=Old);
+return(Old);
+}
+#endif //InterlockedOr64
+
+
+#ifndef InterlockedXor64
+LONGLONG FORCEINLINE InterlockedXor64(LONGLONG volatile *Destination,LONGLONG Value)
+{
+ LONGLONG Old;
+
+ do
+ {
+ Old=*Destination;
+ }while(InterlockedCompareExchange64(Destination,(Old^Value),Old)!=Old);
+return(Old);
+}
+#endif //InterlockedXor64
+#endif //InterlockedCompareExchange64
+
+
+
+
+
+#ifndef InterlockedIncrementPointer
+#if defined(_WIN64)
+#define InterlockedIncrementPointer(lpAddend) (LPVOID)InterlockedIncrement64((LONGLONG volatile*)lpAddend)
+#else
+#define InterlockedIncrementPointer(lpAddend) (LPVOID)InterlockedIncrement((LONG volatile*)lpAddend)
+#endif
+#endif //InterlockedIncrementPointer
+
+
+#ifndef InterlockedDecrementPointer
+#if defined(_WIN64)
+#define InterlockedDecrementPointer(lpAddend) (LPVOID)InterlockedDecrement64((LONGLONG volatile*)lpAddend)
+#else
+#define InterlockedDecrementPointer(lpAddend) (LPVOID)InterlockedDecrement((LONG volatile*)lpAddend)
+#endif
+#endif //InterlockedDecrementPointer
+
+
+
+
+
+#endif // !defined(AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/InternetTime.h b/protocols/MRA/Sdk/InternetTime.h
new file mode 100644
index 0000000000..9999119e6a
--- /dev/null
+++ b/protocols/MRA/Sdk/InternetTime.h
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_INTERNET_TIME_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_)
+#define AFX_INTERNET_TIME_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#include <StrToNum.h>
+#include <MemoryFind.h>
+#include <MemoryFindByte.h>
+
+
+
+typedef struct
+{
+ LONG lTimeZone;
+ SYSTEMTIME stTime;
+} INTERNET_TIME;
+
+
+static LPCSTR lpcszenmMonthEnum[13]= {"---","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
+static LPCSTR lpcszenmDayOfWeakEnum[7]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+
+#define CRLF "\r\n"
+#define LF "\n"
+//WSP++
+#define LWSHT "\r\n\t"
+#define LWSSP "\r\n "
+//WSP--
+
+//FWS++
+#define FWSHT LWSHT
+#define FWSSP LWSSP
+//FWS--
+
+#define SEPARATOR "\r\n\r\n"
+
+
+//DWORD InternetTimeGetTime (LPCSTR lpszTime,SIZE_T dwTimeSize,INTERNET_TIME *pitTime);
+//BOOL SkeepSPWSP (LPCSTR lpszBuff,SIZE_T dwBuffSize,LPSTR *plpszRetBuff,SIZE_T *pdwRetBuffSize);
+//BOOL WSP2SP (LPCSTR lpszBuff,SIZE_T dwBuffSize,LPSTR lpszRetBuff,SIZE_T *pdwRetBuffSize);
+
+
+
+
+
+__inline BOOL SkeepSPWSP(LPCSTR lpszBuff,SIZE_T dwBuffSize,LPSTR *plpszRetBuff,SIZE_T *pdwRetBuffSize)
+{
+ BOOL bRet=TRUE;
+
+ if (lpszBuff && dwBuffSize && (plpszRetBuff || pdwRetBuffSize))
+ {
+ while ((*lpszBuff)<33 && dwBuffSize)
+ {
+ dwBuffSize--;
+ lpszBuff++;
+ }
+
+ if (plpszRetBuff) (*plpszRetBuff)=(LPSTR)lpszBuff;
+ if (pdwRetBuffSize) (*pdwRetBuffSize)=dwBuffSize;
+ }else{
+ bRet=FALSE;
+ }
+return(bRet);
+}
+
+
+__inline BOOL WSP2SP(LPCSTR lpszBuff,SIZE_T dwBuffSize,LPSTR lpszRetBuff,SIZE_T *pdwRetBuffSize)
+{// WSP->SP
+ BOOL bRet=TRUE;
+
+ if (lpszBuff && dwBuffSize && lpszRetBuff)
+ {
+ LPSTR lpszCurReadPos,pCRLF,lpszCurWritePos;
+ SIZE_T dwToCopy,dwRetBuffSize;
+
+ pCRLF=(LPSTR)lpszBuff;
+ lpszCurReadPos=(LPSTR)lpszBuff;
+ lpszCurWritePos=lpszRetBuff;
+ dwRetBuffSize=0;
+
+ while(pCRLF)
+ {
+ pCRLF=(LPSTR)MemoryFind((pCRLF-lpszBuff),lpszBuff,(dwBuffSize-1),CRLF,2);
+ if (pCRLF)
+ {
+ pCRLF+=2;
+ if ((*pCRLF)==9 || (*pCRLF)==32)// LWS: <US-ASCII HT, horizontal-tab (9)> || <US-ASCII SP, space (32)>
+ {
+ dwToCopy=((pCRLF-2)-lpszCurReadPos);
+ pCRLF++;
+
+ memmove((LPVOID)lpszCurWritePos,(CONST VOID*)lpszCurReadPos,dwToCopy);
+ dwRetBuffSize+=(dwToCopy+1);
+ lpszCurWritePos+=dwToCopy;
+ lpszCurWritePos[0]=32;
+ lpszCurWritePos++;
+ lpszCurReadPos=pCRLF;
+ }
+ }else{
+ dwToCopy=((lpszBuff+dwBuffSize)-lpszCurReadPos);
+ dwRetBuffSize+=dwToCopy;
+ memmove((LPVOID)lpszCurWritePos,(CONST VOID*)lpszCurReadPos,dwToCopy);
+ }
+ }
+
+ if (pdwRetBuffSize) (*pdwRetBuffSize)=dwRetBuffSize;
+ }else{
+ bRet=FALSE;
+ }
+return(bRet);
+}
+
+
+
+__inline BOOL HT2SP(LPCSTR lpszBuff,SIZE_T dwBuffSize,LPSTR lpszRetBuff,SIZE_T *pdwRetBuffSize)
+{// HT->SP
+ BOOL bRet=TRUE;
+
+ if (lpszBuff && dwBuffSize && lpszRetBuff)
+ {
+ LPSTR lpszCurReadPos,pHT,lpszCurWritePos;
+ SIZE_T dwToCopy,dwRetBuffSize;
+
+ pHT=(LPSTR)lpszBuff;
+ lpszCurReadPos=(LPSTR)lpszBuff;
+ lpszCurWritePos=lpszRetBuff;
+ dwRetBuffSize=0;
+
+ while(pHT)
+ {
+ pHT=(LPSTR)MemoryFind((pHT-lpszBuff),lpszBuff,dwBuffSize,"\t",1);
+ if (pHT)
+ {
+ dwToCopy=(pHT-lpszCurReadPos);
+ pHT++;
+
+ dwRetBuffSize+=(dwToCopy+1);
+ memmove((LPVOID)lpszCurWritePos,(CONST VOID*)lpszCurReadPos,dwToCopy);
+ lpszCurWritePos+=dwToCopy;
+ lpszCurWritePos[0]=32;
+ lpszCurWritePos++;
+ lpszCurReadPos=pHT;
+ }else{
+ dwToCopy=((lpszBuff+dwBuffSize)-lpszCurReadPos);
+ dwRetBuffSize+=dwToCopy;
+ memmove((LPVOID)lpszCurWritePos,(CONST VOID*)lpszCurReadPos,dwToCopy);
+ }
+ }
+
+ if (pdwRetBuffSize) (*pdwRetBuffSize)=dwRetBuffSize;
+ }else{
+ bRet=FALSE;
+ }
+return(bRet);
+}
+
+
+
+
+__inline BOOL CleanUnneededSP(LPCSTR lpszBuff,SIZE_T dwBuffSize,LPSTR lpszRetBuff,SIZE_T *pdwRetBuffSize)
+{// nSP->SP, SPCRLF->CRLF, CRLFSP->CRLF
+ BOOL bRet=TRUE;
+
+ if (lpszBuff && dwBuffSize && lpszRetBuff)
+ {
+ LPSTR lpszCurReadPos,pSP,pSPStart,pSPEnd,lpszCurWritePos,pEnd;
+ SIZE_T dwToCopy,dwRetBuffSize;
+
+ pSP=(LPSTR)lpszBuff;
+ lpszCurReadPos=(LPSTR)lpszBuff;
+ lpszCurWritePos=lpszRetBuff;
+ pEnd=((LPSTR)lpszBuff+dwBuffSize);
+ dwRetBuffSize=0;
+
+ while(pSP)
+ {
+ pSP=(LPSTR)MemoryFind((pSP-lpszBuff),lpszBuff,dwBuffSize," ",1);
+ if (pSP)
+ {
+ dwToCopy=(pSP-lpszCurReadPos);
+ pSPStart=pSP;
+ pSPEnd=pSP;
+ while((*pSPEnd)==32 && pSPEnd<pEnd) pSPEnd++;
+
+ // check SP on line start
+ if ((pSPStart-1)>lpszBuff)
+ {
+ if ((*((WORD*)(pSPStart-2)))!=(*((WORD*)CRLF))) dwToCopy++;
+ }else{// buff start
+ if (pSPStart>lpszBuff) dwToCopy++;
+ }
+
+ // check SP on line end
+ if ((pSPEnd+1)<=pEnd)
+ {
+ if ((*((WORD*)pSPEnd))!=(*((WORD*)CRLF))) dwToCopy++;
+ }else{// buff start
+ if (pSPEnd>lpszBuff) dwToCopy++;
+ }
+
+ memmove((LPVOID)lpszCurWritePos,(CONST VOID*)lpszCurReadPos,dwToCopy);
+ lpszCurWritePos+=dwToCopy;
+ dwRetBuffSize+=dwToCopy;
+ lpszCurReadPos=pSPEnd;
+ pSP=pSPEnd;
+ }else{
+ dwToCopy=((lpszBuff+dwBuffSize)-lpszCurReadPos);
+ dwRetBuffSize+=dwToCopy;
+ memmove((LPVOID)lpszCurWritePos,(CONST VOID*)lpszCurReadPos,dwToCopy);
+ }
+ }
+
+ if (pdwRetBuffSize) (*pdwRetBuffSize)=dwRetBuffSize;
+ }else{
+ bRet=FALSE;
+ }
+return(bRet);
+}
+
+
+
+
+__inline SIZE_T CopyText(LPVOID lpOutBuff,LPCVOID lpcBuff,SIZE_T dwLen)
+{
+ SIZE_T dwRet=0;
+
+ if (lpOutBuff && lpcBuff && dwLen)
+ {
+ BYTE bt;
+ LPBYTE lpbtIn=(LPBYTE)lpcBuff,lpbtOut=(LPBYTE)lpOutBuff;
+
+ for(SIZE_T i=dwLen;i;i--)
+ {
+ bt=(*(lpbtIn++));
+ if (bt<127 && (bt>31 || bt==9 || bt==10 || bt==13))
+ {
+ (*(lpbtOut++))=bt;
+ dwRet++;
+ }
+ }
+ }
+return(dwRet);
+}
+
+
+__inline void InternetTimeGetCurrentTime(INTERNET_TIME *pitTime)
+{
+ TIME_ZONE_INFORMATION tzi={0};
+ GetTimeZoneInformation(&tzi);
+ pitTime->lTimeZone=tzi.Bias;
+ GetSystemTime(&pitTime->stTime);
+}
+
+
+__inline DWORD InternetTimeGetString(INTERNET_TIME *pitTime,LPSTR lpszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet)
+{// Переводит время из MAILTIME в строковое
+ DWORD dwRet=NO_ERROR;
+
+ if (dwBuffSize>31)
+ {
+ LPSTR lpszCurPos=lpszBuff;
+ SIZE_T dwTimeLen=0,dwtm;
+
+ // day of weak// date of mounth// mounth name// year// hours // minutes// seconds
+ dwtm=wsprintfA(lpszCurPos,"%s, %02lu %s %04lu %02lu:%02lu:%02lu ",lpcszenmDayOfWeakEnum[pitTime->stTime.wDayOfWeek],pitTime->stTime.wDay,lpcszenmMonthEnum[pitTime->stTime.wMonth],pitTime->stTime.wYear,pitTime->stTime.wHour,pitTime->stTime.wMinute,pitTime->stTime.wSecond);
+ lpszCurPos+=dwtm;
+ dwTimeLen+=dwtm;
+
+ // time zone
+ if (pitTime->lTimeZone)
+ {
+ if (pitTime->lTimeZone < 0)
+ {// нужно добавить плюсик, минус добавляется автоматом
+ (*((BYTE*)lpszCurPos))='+';
+ lpszCurPos++;
+ dwTimeLen++;
+ }
+
+ dwtm=wsprintfA(lpszCurPos,"%04ld",-(((pitTime->lTimeZone/60)*100)+pitTime->lTimeZone%60));
+ lpszCurPos+=dwtm;
+ dwTimeLen+=dwtm;
+ }else{
+ dwtm=wsprintfA(lpszCurPos,"GMT");
+ lpszCurPos+=dwtm;
+ dwTimeLen+=dwtm;
+ }
+
+ if (pdwBuffSizeRet) (*pdwBuffSizeRet)=dwTimeLen;
+ }else{// переданный буффер слишком мал
+ if (pdwBuffSizeRet) (*pdwBuffSizeRet)=32;
+ dwRet=ERROR_INSUFFICIENT_BUFFER;
+ }
+return(dwRet);
+}
+
+
+
+__inline DWORD InternetTimeGetTime(LPCSTR lpszTime,SIZE_T dwTimeSize,INTERNET_TIME *pitTime)
+{// Переводит время из строкового в INTERNET_TIME
+ DWORD dwRet=NO_ERROR;
+
+ if (lpszTime && dwTimeSize && dwTimeSize<4097 && pitTime)
+ {// = Thu, 21 May 1998 05:33:29 -0700 =
+ char sztmBuff[4096];
+ LPSTR lpszCurPos=sztmBuff,lpszTemp;
+ SIZE_T i,dwCurSize=4096,dwTemp;
+
+ memset(pitTime, 0, sizeof(INTERNET_TIME));
+ WSP2SP((LPSTR)lpszTime,dwTimeSize,lpszCurPos,&dwCurSize);
+
+ if (dwCurSize>3)
+ {// день недели
+ if (lpszCurPos[3]==',')
+ {
+ for (i=0;i<8;i++)
+ {
+ if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpcszenmDayOfWeakEnum[i],3,lpszCurPos,3)==CSTR_EQUAL)
+ {
+ pitTime->stTime.wDayOfWeek=(unsigned short)i;
+ break;
+ }
+ }
+
+ lpszCurPos+=4;
+ dwCurSize-=4;
+ }
+
+ if (dwCurSize>2)
+ {// день месяца
+ SkeepSPWSP(lpszCurPos,dwCurSize,&lpszCurPos,&dwCurSize);
+ if ((lpszTemp=(LPSTR)MemoryFindByte(0,lpszCurPos,dwCurSize,' ')))
+ {
+ dwTemp=(lpszTemp-lpszCurPos);
+ pitTime->stTime.wDay=(unsigned short)StrToUNum32(lpszCurPos,dwTemp);
+
+ lpszCurPos=(lpszTemp+1);
+ dwCurSize-=(dwTemp+1);
+
+ if (dwCurSize>3)
+ {// месяц
+ SkeepSPWSP(lpszCurPos,dwCurSize,&lpszCurPos,&dwCurSize);
+
+ for (i=1;i<14;i++)
+ {
+ if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpcszenmMonthEnum[i],3,lpszCurPos,3)==CSTR_EQUAL)
+ {
+ pitTime->stTime.wMonth=(unsigned short)i;
+ break;
+ }
+ }
+
+ lpszCurPos+=3;
+ dwCurSize-=3;
+
+
+ if (dwCurSize>3)
+ {// год
+ SkeepSPWSP(lpszCurPos,dwCurSize,&lpszCurPos,&dwCurSize);
+ if ((lpszTemp=(LPSTR)MemoryFindByte(0,lpszCurPos,dwCurSize,' ')))
+ {
+ dwTemp=(lpszTemp-lpszCurPos);
+ pitTime->stTime.wYear=(unsigned short)StrToUNum32(lpszCurPos,dwTemp);
+
+ lpszCurPos=(lpszTemp+1);
+ dwCurSize-=(dwTemp+1);
+
+ if (dwCurSize>2)
+ { // часы
+ SkeepSPWSP(lpszCurPos,dwCurSize,&lpszCurPos,&dwCurSize);
+ if ((lpszTemp=(LPSTR)MemoryFindByte(0,lpszCurPos,dwCurSize,':')))
+ {
+ dwTemp=(lpszTemp-lpszCurPos);
+ pitTime->stTime.wHour=(unsigned short)StrToUNum32(lpszCurPos,dwTemp);
+
+ lpszCurPos=(lpszTemp+1);
+ dwCurSize-=(dwTemp+1);
+
+ if (dwCurSize>2)
+ {// минуты
+ SkeepSPWSP(lpszCurPos,dwCurSize,&lpszCurPos,&dwCurSize);
+ if ((lpszTemp=(LPSTR)MemoryFindByte(0,lpszCurPos,dwCurSize,':')))
+ {
+ dwTemp=(lpszTemp-lpszCurPos);
+ pitTime->stTime.wMinute=(unsigned short)StrToUNum32(lpszCurPos,dwTemp);
+
+ lpszCurPos=(lpszTemp+1);
+ dwCurSize-=(dwTemp+1);
+
+ if (dwCurSize>2)
+ {// секунды, они есть
+ if ((lpszTemp=(LPSTR)MemoryFindByte(0,lpszCurPos,dwCurSize,' ')))
+ {
+ dwTemp=(lpszTemp-lpszCurPos);
+ pitTime->stTime.wSecond=(unsigned short)StrToUNum32(lpszCurPos,dwTemp);
+
+ lpszCurPos=(lpszTemp+1);
+ dwCurSize-=(dwTemp+1);
+ }
+ }else{// зоны нет
+ if (dwCurSize)
+ {
+ pitTime->stTime.wSecond=(unsigned short)StrToUNum32(lpszCurPos,dwCurSize);
+ lpszCurPos+=dwCurSize;
+ dwCurSize=0;
+ }
+ }
+ }else{
+ if ((lpszTemp=(LPSTR)MemoryFindByte(0,lpszCurPos,dwCurSize,' ')))
+ {
+ dwTemp=(lpszTemp-lpszCurPos);
+ pitTime->stTime.wMinute=(unsigned short)StrToUNum32(lpszCurPos,dwTemp);
+
+ lpszCurPos=(lpszTemp+1);
+ dwCurSize-=(dwTemp+1);
+ }
+ }
+
+ if (dwCurSize)
+ {// часовой пояс
+ SkeepSPWSP(lpszCurPos,dwCurSize,&lpszCurPos,&dwCurSize);
+ pitTime->lTimeZone=(LONG)StrToNum(lpszCurPos,dwCurSize);
+ if (pitTime->lTimeZone>1300 || pitTime->lTimeZone<-1200) pitTime->lTimeZone=2400;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }else{
+ dwRet=ERROR_INVALID_HANDLE;
+ }
+return(dwRet);
+}
+
+
+
+#endif // !defined(AFX_INTERNET_TIME_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_)
diff --git a/protocols/MRA/Sdk/ListMT.h b/protocols/MRA/Sdk/ListMT.h
new file mode 100644
index 0000000000..66e118867d
--- /dev/null
+++ b/protocols/MRA/Sdk/ListMT.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_LIST_MT__H__INCLUDED_)
+#define AFX_LIST_MT__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#include <InterlockedFunctions.h>
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size
+#endif
+#endif
+
+
+// структура для работы со списком, элемент списка
+typedef struct _LIST_MT_ITEM
+{
+#ifdef __cplusplus
+ _LIST_MT_ITEM *plmtiPrev; // *предыдущий элемент в списке
+ _LIST_MT_ITEM *plmtiNext; // *следующий элемент в списке
+#else
+ LPVOID *plmtiPrev; // *предыдущий элемент в списке
+ LPVOID *plmtiNext; // *следующий элемент в списке
+#endif
+ LPVOID lpListMT; // указатель на заголовок списка, см структуру ниже
+ LPVOID lpData; // указатель на данные, связанные с элементом списка
+}LIST_MT_ITEM, *PLIST_MT_ITEM, *LPLIST_MT_ITEM;
+typedef CONST PLIST_MT_ITEM PCLIST_MT_ITEM, LPCLIST_MT_ITEM;
+
+
+// структура для работы со списком, заголовок списка
+typedef struct _LIST_MT
+{
+ SIZE_T nCount; // *колличество элементов в списке
+ PLIST_MT_ITEM plmtiFirst; // *указывает на первый элемент в списке
+ PLIST_MT_ITEM plmtiLast; // *указывает на последний элемент в списке
+ CRITICAL_SECTION cs; // *section for exclysive access to List
+}LIST_MT, *PLIST_MT, *LPLIST_MT;
+typedef CONST PLIST_MT PCLIST_MT, LPCLIST_MT;
+
+
+// структура для работы с итератором
+typedef struct _LIST_MT_ITERATOR
+{
+ PLIST_MT_ITEM plmtListMTItem;
+}LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR;
+//typedef LIST_MT_ITEM LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR;
+typedef CONST PLIST_MT_ITERATOR PCLIST_MT_ITERATOR, LPCLIST_MT_ITERATOR;
+
+
+
+
+__inline DWORD ListMTInitialize(PCLIST_MT pclmtListMT,DWORD dwSpinCount)
+{
+ DWORD dwRetErrorCode;
+
+#if (_WIN32_WINNT >= 0x0403)
+ if (InitializeCriticalSectionAndSpinCount(&pclmtListMT->cs,((dwSpinCount)? (dwSpinCount | 0x80000000):0L)))
+#else
+ InitializeCriticalSection(&pclmtListMT->cs);
+ if (TRUE)
+#endif
+ {
+ InterlockedExchangePointer((volatile PVOID*)&pclmtListMT->nCount,NULL);
+ pclmtListMT->plmtiFirst=NULL;
+ pclmtListMT->plmtiLast=NULL;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=GetLastError();
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline void ListMTDestroy(PCLIST_MT pclmtListMT)
+{
+ InterlockedExchangePointer((volatile PVOID*)&pclmtListMT->nCount,NULL);
+ pclmtListMT->plmtiFirst=NULL;
+ pclmtListMT->plmtiLast=NULL;
+ DeleteCriticalSection(&pclmtListMT->cs);
+ SecureZeroMemory(&pclmtListMT->cs,sizeof(CRITICAL_SECTION));
+}
+
+
+__inline BOOL ListMTTryLock(PCLIST_MT pclmtListMT)
+{
+#if (_WIN32_WINNT >= 0x0400)
+ return(TryEnterCriticalSection(&pclmtListMT->cs));
+#else
+ return(FALSE);
+#endif
+}
+
+
+__inline void ListMTLock(PCLIST_MT pclmtListMT)
+{
+ EnterCriticalSection(&pclmtListMT->cs);
+}
+
+
+__inline void ListMTUnLock(PCLIST_MT pclmtListMT)
+{
+ LeaveCriticalSection(&pclmtListMT->cs);
+}
+
+
+__inline SIZE_T ListMTGetCount(PCLIST_MT pclmtListMT)
+{
+ return((SIZE_T)InterlockedCompareExchangePointer((LPVOID*)&pclmtListMT->nCount,NULL,NULL));
+}
+
+
+__inline SIZE_T ListMTItemAdd(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem,LPVOID lpData)
+{
+ SIZE_T dwRet=(SIZE_T)InterlockedIncrementPointer(&pclmtListMT->nCount);//pclmtListMT->nCount++;
+ pclmtListMTItem->lpData=lpData;
+ pclmtListMTItem->lpListMT=pclmtListMT;
+
+ if (pclmtListMT->plmtiLast)
+ {// add node to end of list
+ pclmtListMTItem->plmtiPrev=pclmtListMT->plmtiLast;
+ pclmtListMTItem->plmtiNext=NULL;
+ pclmtListMT->plmtiLast->plmtiNext=pclmtListMTItem;
+ pclmtListMT->plmtiLast=pclmtListMTItem;
+ }else{// add the first node to the linked list
+ pclmtListMTItem->plmtiPrev=NULL;
+ pclmtListMTItem->plmtiNext=NULL;
+ pclmtListMT->plmtiFirst=pclmtListMTItem;
+ pclmtListMT->plmtiLast=pclmtListMTItem;
+ }
+
+return(dwRet);
+}
+
+
+__inline DWORD ListMTItemDelete(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem)
+{
+ DWORD dwRetErrorCode;
+
+ if (pclmtListMTItem->lpListMT==pclmtListMT && pclmtListMT)
+ {// Данный элемент принадлежит к этому списку, можно удалить.
+ PLIST_MT_ITEM plmtiPrevNode=pclmtListMTItem->plmtiPrev,plmtiNextNode=pclmtListMTItem->plmtiNext;
+
+ if (plmtiPrevNode || plmtiNextNode)
+ {
+ if (plmtiPrevNode && plmtiNextNode==NULL)
+ {// This is the start node in the list to delete
+ // отключился последний подключившийся
+ plmtiPrevNode->plmtiNext=NULL;
+ pclmtListMT->plmtiLast=plmtiPrevNode;
+ }else{
+ if (plmtiPrevNode==NULL && plmtiNextNode)
+ {// This is the end node in the list to delete
+ // отключился первый подключившийся
+ plmtiNextNode->plmtiPrev=NULL;
+ pclmtListMT->plmtiFirst=plmtiNextNode;
+ }else{// оключился клиент не первый и не последний
+ //if (plmtiPrev && plmtiNext)
+ {// Neither start node nor end node in the list
+ plmtiPrevNode->plmtiNext=plmtiNextNode;
+ plmtiNextNode->plmtiPrev=plmtiPrevNode;
+ }
+ }
+ }
+ }else{// This is the only node in the list to delete
+ pclmtListMT->plmtiFirst=NULL;
+ pclmtListMT->plmtiLast=NULL;
+ }
+
+ pclmtListMTItem->lpListMT=NULL;
+ InterlockedDecrementPointer(&pclmtListMT->nCount);// pclmtListMT->nCount--;
+ dwRetErrorCode=NO_ERROR;
+ }else{// попытались удалить элемент не относящийся к данному списку
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline LPVOID ListMTItemDataGet(PCLIST_MT_ITEM pclmtListMTItem)
+{
+ return(pclmtListMTItem->lpData);
+}
+
+
+__inline void ListMTItemDataSet(PCLIST_MT_ITEM pclmtListMTItem, LPVOID lpData)
+{
+ pclmtListMTItem->lpData=lpData;
+}
+
+
+__inline DWORD ListMTItemGetFirst(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ DWORD dwRetErrorCode;
+
+ if (pclmtListMT->plmtiFirst)
+ {
+ if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiFirst;
+ if (plpData) (*plpData)=pclmtListMT->plmtiFirst->lpData;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_NO_MORE_ITEMS;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD ListMTItemGetLast(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ DWORD dwRetErrorCode;
+
+ if (pclmtListMT->plmtiLast)
+ {
+ if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiLast;
+ if (plpData) (*plpData)=pclmtListMT->plmtiLast->lpData;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_NO_MORE_ITEMS;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+__inline void ListMTItemSwap(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem1,PCLIST_MT_ITEM pclmtListMTItem2)
+{// поменять два элемента списка местами, даже если они из разных списков
+
+ if (pclmtListMTItem1!=pclmtListMTItem2)
+ {// это разные элементы списка
+ PLIST_MT_ITEM lpTemp;
+
+ lpTemp=pclmtListMTItem1->plmtiPrev;
+ if ((pclmtListMTItem1->plmtiPrev=pclmtListMTItem2->plmtiPrev)==NULL)
+ {// pclmtListMTItem2 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem1
+ pclmtListMT->plmtiFirst=pclmtListMTItem1;
+ }
+
+ if ((pclmtListMTItem2->plmtiPrev=lpTemp)==NULL)
+ {// pclmtListMTItem1 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem2
+ pclmtListMT->plmtiFirst=pclmtListMTItem2;
+ }
+
+
+ lpTemp=pclmtListMTItem1->plmtiNext;
+ if ((pclmtListMTItem1->plmtiNext=pclmtListMTItem2->plmtiNext)==NULL)
+ {// pclmtListMTItem2 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem1
+ pclmtListMT->plmtiLast=pclmtListMTItem1;
+ }
+
+ if ((pclmtListMTItem2->plmtiNext=lpTemp)==NULL)
+ {// pclmtListMTItem1 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem2
+ pclmtListMT->plmtiLast=pclmtListMTItem2;
+ }
+ }
+}
+
+
+__inline BOOL ListMTIteratorMoveFirst(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiFirst)? TRUE:FALSE);
+}
+
+
+__inline BOOL ListMTIteratorMoveLast(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiLast)? TRUE:FALSE);
+}
+
+
+__inline BOOL ListMTIteratorMovePrev(PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ BOOL bRet=FALSE;
+
+ if (pclmtiIterator->plmtListMTItem)
+ {
+ if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiPrev) bRet=TRUE;
+ }
+return(bRet);
+}
+
+
+__inline BOOL ListMTIteratorMoveNext(PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ BOOL bRet=FALSE;
+
+ if (pclmtiIterator->plmtListMTItem)
+ {
+ if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiNext) bRet=TRUE;
+ }
+return(bRet);
+}
+
+
+__inline DWORD ListMTIteratorGet(PCLIST_MT_ITERATOR pclmtiIterator,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ DWORD dwRetErrorCode;
+
+ if (pclmtiIterator->plmtListMTItem)
+ {
+ if (pplmtListMTItem) (*pplmtListMTItem)=pclmtiIterator->plmtListMTItem;
+ if (plpData) (*plpData)=pclmtiIterator->plmtListMTItem->lpData;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_NO_MORE_ITEMS;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#else
+#pragma warning(default:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size
+#endif
+#endif
+#endif
+
+
+
+#endif // !defined(AFX_LIST_MT__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/MemoryCompare.h b/protocols/MRA/Sdk/MemoryCompare.h
new file mode 100644
index 0000000000..17ef96f35a
--- /dev/null
+++ b/protocols/MRA/Sdk/MemoryCompare.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_MEMORYCOMPARE__H__INCLUDED_)
+#define AFX_MEMORYCOMPARE__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+// If the string pointed to by lpString1 is less than the string pointed
+// to by lpString2, the return value is negative.
+// If the string pointed to by lpString1 is greater than the string pointed
+// to by lpString2, the return value is positive.
+// If the strings are equal, the return value is zero.
+//
+// lpString1<lpString2 >> ret=1=CSTR_LESS_THAN
+// lpString1=lpString2 >> ret=2=CSTR_EQUAL
+// lpString1>lpString2 >> ret=3=CSTR_GREATER_THAN
+
+#define CMEM_EQUAL 0
+#define CMEM_GREATER_THAN 1
+#define CMEM_LESS_THAN 2
+
+
+__inline unsigned int MemoryCompare(const void *pBuff1,size_t dwBuff1Size,const void *pBuff2,size_t dwBuff2Size)
+{
+ unsigned int uiRet;
+
+ if (dwBuff1Size==dwBuff2Size)
+ {
+ if (pBuff1==pBuff2)
+ {
+ uiRet=CMEM_EQUAL;
+ }else{
+ if (pBuff1 && pBuff2)
+ {
+ int iRet;
+
+ iRet=memcmp(pBuff1,pBuff2,dwBuff1Size);
+ if (iRet==0)
+ {
+ uiRet=CMEM_EQUAL;
+ }else{
+ if (iRet<0)
+ {
+ uiRet=CMEM_GREATER_THAN;
+ }else{
+ uiRet=CMEM_LESS_THAN;
+ }
+ }
+ }else{
+ if (pBuff1)
+ {//pBuff2==NULL
+ uiRet=CMEM_GREATER_THAN;
+ }else{//pBuff1==NULL
+ uiRet=CMEM_LESS_THAN;
+ }
+ }
+ }
+ }else{
+ if (dwBuff1Size<dwBuff2Size)
+ {
+ uiRet=CMEM_LESS_THAN;
+ }else{
+ uiRet=CMEM_GREATER_THAN;
+ }
+ }
+return(uiRet);
+}
+
+
+
+#endif // !defined(AFX_MEMORYCOMPARE__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/MemoryFind.h b/protocols/MRA/Sdk/MemoryFind.h
new file mode 100644
index 0000000000..860c5ce20a
--- /dev/null
+++ b/protocols/MRA/Sdk/MemoryFind.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#if !defined(AFX_MEMORYFIND__H__INCLUDED_)
+#define AFX_MEMORYFIND__H__INCLUDED_
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+__inline void *MemoryFind(size_t dwFrom,const void *pBuff,size_t dwBuffSize,const void *pWhatFind,size_t dwWhatFindSize)
+{
+ void *pRet=NULL;
+
+ if (pBuff && dwBuffSize && pWhatFind && dwWhatFindSize && (dwFrom+dwWhatFindSize)<=dwBuffSize)
+ {
+ if (dwWhatFindSize==1)
+ {// MemoryFindByte
+ pRet=(void*)memchr((const void*)(((size_t)pBuff)+dwFrom),(*((unsigned char*)pWhatFind)),(dwBuffSize-dwFrom));
+ }else{
+ void *pCurPos;
+
+ pCurPos=(void*)(((size_t)pBuff)+dwFrom);
+
+ if ((dwFrom+dwWhatFindSize)==dwBuffSize)
+ {// only MemoryCompare
+ if (memcmp(pCurPos,pWhatFind,dwWhatFindSize)==0) pRet=pCurPos;
+ }else{
+ dwBuffSize-=(dwWhatFindSize-1);
+
+ while(pCurPos)
+ {
+ pCurPos=memchr(pCurPos,(*((unsigned char*)pWhatFind)),(dwBuffSize-(((size_t)pCurPos)-((size_t)pBuff))));
+ if (pCurPos)
+ {
+ if (memcmp(pCurPos,pWhatFind,dwWhatFindSize)==0)
+ {
+ pRet=pCurPos;
+ break;
+ }else{
+ pCurPos=(void*)(((size_t)pCurPos)+1);
+ }
+ }
+ }
+ }
+ }
+ }
+return(pRet);
+}
+
+
+#endif // !defined(AFX_MEMORYFIND__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/MemoryFindByte.h b/protocols/MRA/Sdk/MemoryFindByte.h
new file mode 100644
index 0000000000..a18a721b9d
--- /dev/null
+++ b/protocols/MRA/Sdk/MemoryFindByte.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_MEMORYFINDBYTE__H__INCLUDED_)
+#define AFX_MEMORYFINDBYTE__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+__inline void *MemoryFindByte(size_t dwFrom,const void *pBuff,size_t dwBuffSize,unsigned char chWhatFind)
+{
+ void *pRet=NULL;
+
+ if (pBuff && dwBuffSize && dwFrom<dwBuffSize)
+ {
+ pRet=(void*)memchr((const void*)(((size_t)pBuff)+dwFrom),chWhatFind,(dwBuffSize-dwFrom));
+ }
+return(pRet);
+}
+
+
+#ifndef _WIN64
+__inline void *MemoryFindByteReverse(size_t dwFrom,const void *pBuff,size_t dwBuffSize,unsigned char chWhatFind)
+{
+ void *pRet=NULL;
+
+ __asm
+ {
+ push ebx // сохраняем регистр
+ push edi // сохраняем регистр
+ push esi // сохраняем регистр
+
+ mov ecx,dwBuffSize
+ test ecx,ecx //; проверка входного параметра, он !=0
+ je short end_func
+
+ mov edi,pBuff //; di = string
+ test edi,edi //; проверка входного параметра, он !=0
+ jz short end_func
+
+ mov eax,dwFrom
+
+/////////////////////////////////////////////
+ cmp eax,ecx //; проверка ecx(=len)=>dwFrom
+ jae short end_func
+
+ std //; count 'up' on string this time
+ sub ecx,eax //; уменьшаем длинну на dwFrom(нач смещен)
+ add edi,ecx //; сдвигаем начало на dwSourceSize(на конец)
+ mov al,chWhatFind //; al=search byte
+ repne scasb //; find that byte
+ inc edi //; di points to byte which stopped scan
+ cmp [edi],al //; see if we have a hit
+ jne short end_func //; yes, point to byte
+ mov pRet,edi //; ax=pointer to byte
+ end_func:
+
+ cld
+ pop esi // восстанавливаем содержимое регистра
+ pop edi // восстанавливаем содержимое регистра
+ pop ebx // восстанавливаем содержимое регистра
+ }
+return(pRet);
+}
+#endif
+
+
+#endif // !defined(AFX_MEMORYFINDBYTE__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/MemoryReplace.h b/protocols/MRA/Sdk/MemoryReplace.h
new file mode 100644
index 0000000000..c911ccfbe1
--- /dev/null
+++ b/protocols/MRA/Sdk/MemoryReplace.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2010 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#if !defined(AFX_MEMORY_REPLACE__H__INCLUDED_)
+#define AFX_MEMORY_REPLACE__H__INCLUDED_
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#ifndef DebugBreak
+#define DebugBreak()
+#endif
+
+
+#ifdef MEMALLOC
+#define MEMORY_REPLACE_MEMALLOC(Size) MEMALLOC(Size)
+#define MEMORY_REPLACE_MEMFREE(Mem) MEMFREE(Mem)
+#else
+#define MEMORY_REPLACE_MEMALLOC(Size) malloc(((Size)+sizeof(void*)))
+#define MEMORY_REPLACE_MEMFREE(Mem) if ((Mem)) {free((void*)(Mem));(Mem)=NULL;}
+#endif
+
+
+// 0 - all ok
+// -1 - bad params
+// -2 - small dst buff
+// -3 - memory allocation failed
+
+__inline int MemoryReplaceEx(void *pSrcBuff,size_t dwSrcBuffSize,size_t dwReplaceItemsCount,void **ppInReplaceItems,size_t *pdwInReplaceItemsCounts,void **ppOutReplaceItems,size_t *pdwOutReplaceItemsCounts,void *pDstBuff,size_t dwDstBuffSize,size_t *pdwDstBuffSize,size_t *pdwReplacesCount)
+{
+ int iRet=-1;
+
+ if (pSrcBuff && dwSrcBuffSize && (dwReplaceItemsCount==0 || (dwReplaceItemsCount && ppInReplaceItems && pdwInReplaceItemsCounts && ppOutReplaceItems && pdwOutReplaceItemsCounts)) && pDstBuff && dwDstBuffSize)
+ {
+ if (dwReplaceItemsCount==0)
+ {// no replace, copy mem
+ if (dwDstBuffSize>=dwSrcBuffSize)
+ {
+ memmove(pDstBuff,pSrcBuff,dwSrcBuffSize);
+ if (pdwDstBuffSize) (*pdwDstBuffSize)=dwSrcBuffSize;
+ if (pdwReplacesCount) (*pdwReplacesCount)=0;
+ iRet=0;
+ }else{// small dst buff
+ iRet=-2;
+ }
+ }else{
+ unsigned char **ppFounded;
+
+ ppFounded=(unsigned char**)MEMORY_REPLACE_MEMALLOC((sizeof(unsigned char*)*dwReplaceItemsCount));
+ if (ppFounded)
+ {
+ unsigned char *pDstBuffCur,*pSrcBuffCur,*pSrcBuffCurPrev,*pDstBuffMax;
+ size_t i,dwFirstFoundedIndex,dwFoundedCount,dwMemPartToCopy,dwReplacesCount;
+
+ pSrcBuffCurPrev=(unsigned char*)pSrcBuff;
+ pDstBuffCur=(unsigned char*)pDstBuff;
+ pDstBuffMax=(((unsigned char*)pDstBuff)+dwDstBuffSize);
+ dwFirstFoundedIndex=0;
+ dwFoundedCount=0;
+ dwReplacesCount=0;
+
+ for(i=0;i<dwReplaceItemsCount;i++)
+ {// loking for in first time
+ ppFounded[i]=(unsigned char*)MemoryFind((pSrcBuffCurPrev-(unsigned char*)pSrcBuff),pSrcBuff,dwSrcBuffSize,ppInReplaceItems[i],pdwInReplaceItemsCounts[i]);
+ if (ppFounded[i]) dwFoundedCount++;
+ }
+
+ while(dwFoundedCount)
+ {
+ for(i=0;i<dwReplaceItemsCount;i++)
+ {// looking for first to replace
+ if (ppFounded[i] && (ppFounded[i]<ppFounded[dwFirstFoundedIndex] || ppFounded[dwFirstFoundedIndex]==NULL)) dwFirstFoundedIndex=i;
+ }
+
+ if (ppFounded[dwFirstFoundedIndex])
+ {// in founded
+ dwMemPartToCopy=(ppFounded[dwFirstFoundedIndex]-pSrcBuffCurPrev);
+ if (pDstBuffMax>(pDstBuffCur+(dwMemPartToCopy+pdwInReplaceItemsCounts[dwFirstFoundedIndex])))
+ {
+ dwReplacesCount++;
+ memmove(pDstBuffCur,pSrcBuffCurPrev,dwMemPartToCopy);pDstBuffCur+=dwMemPartToCopy;
+ memmove(pDstBuffCur,ppOutReplaceItems[dwFirstFoundedIndex],pdwOutReplaceItemsCounts[dwFirstFoundedIndex]);pDstBuffCur+=pdwOutReplaceItemsCounts[dwFirstFoundedIndex];
+ pSrcBuffCurPrev=(ppFounded[dwFirstFoundedIndex]+pdwInReplaceItemsCounts[dwFirstFoundedIndex]);
+
+ for(i=0;i<dwReplaceItemsCount;i++)
+ {// loking for in next time // update founded records
+ if (ppFounded[i] && ppFounded[i]<pSrcBuffCurPrev)
+ {
+ ppFounded[i]=(unsigned char*)MemoryFind((pSrcBuffCurPrev-(unsigned char*)pSrcBuff),pSrcBuff,dwSrcBuffSize,ppInReplaceItems[i],pdwInReplaceItemsCounts[i]);
+ if (ppFounded[i]==NULL) dwFoundedCount--;
+ }
+ }
+ }else{// ERROR_BUFFER_OVERFLOW
+ iRet=-2;
+ DebugBreak();
+ break;
+ }
+ }else{// сюда по идее никогда не попадём, на всякий случай.
+ DebugBreak();
+ break;
+ }
+ }
+ pSrcBuffCur=(((unsigned char*)pSrcBuff)+dwSrcBuffSize);
+ memmove(pDstBuffCur,pSrcBuffCurPrev,(pSrcBuffCur-pSrcBuffCurPrev));
+ pDstBuffCur+=(pSrcBuffCur-pSrcBuffCurPrev);
+ (*((unsigned short*)pDstBuffCur))=0;
+
+ MEMORY_REPLACE_MEMFREE(ppFounded);
+
+ if (pdwDstBuffSize) (*pdwDstBuffSize)=(pDstBuffCur-((unsigned char*)pDstBuff));
+ if (pdwReplacesCount) (*pdwReplacesCount)=dwReplacesCount;
+ iRet=0;
+ }else{
+ iRet=-3;
+ }
+ }
+ }
+return(iRet);
+}
+
+
+#endif // !defined(AFX_MEMORY_REPLACE__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/RC4.h b/protocols/MRA/Sdk/RC4.h
new file mode 100644
index 0000000000..82e1da0de4
--- /dev/null
+++ b/protocols/MRA/Sdk/RC4.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2007 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_RC4__H__INCLUDED_)
+#define AFX_RC4__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+__inline void RC4(LPBYTE lpBuff,SIZE_T dwBuffSize,LPBYTE lpKey,SIZE_T dwKeySize)
+{// RC4
+// www.codeproject.com/cpp/crypt_routine.asp%3Fdf%3D100%26forumid%3D4418%26exp%3D0%26select%3D251879+RC4+c%2B%2B+source+DWORD&hl=ru&gl=ru&ct=clnk&cd=2
+// http://www.thecodeproject.com/cpp/crypt_routine.asp
+// http://forum.ixbt.com/topic.cgi?id=40:3020
+
+ //we will consider size of sbox 256 bytes
+ //(extra byte are only to prevent any mishep just in case)
+ BYTE temp;
+ BYTE Sbox[260]={0},Sbox2[260]={0};
+ SIZE_T i,j,t,x;
+
+ i=j=t=x=0;
+ temp=0;
+
+ //initialize sbox i
+ for(i=0;i<256;i++) Sbox[i]=(BYTE)i;
+
+ j=0;
+ //whether user has sent any inpur lpKey
+ //initialize the sbox2 with user lpKey
+ for(i=0;i<256;i++)
+ {
+ if (j==dwKeySize) j=0;
+ Sbox2[i]=lpKey[j++];
+ }
+
+ j=0; //Initialize j
+ //scramble sbox1 with sbox2
+ for(i=0;i<256;i++)
+ {
+ j=(j+(unsigned long)Sbox[i]+(unsigned long)Sbox2[i]) % 256U;
+ temp=Sbox[i];
+ Sbox[i]=Sbox[j];
+ Sbox[j]=temp;
+ }
+
+ i=j=0;
+ for(x=0;x<dwBuffSize;x++)
+ {
+ //increment i
+ i=(i+1U)%256U;
+ //increment j
+ j=(j+(unsigned long)Sbox[i])%256U;
+
+ //Scramble SBox #1 further so encryption routine will
+ //will repeat itself at great interval
+ temp=Sbox[i];
+ Sbox[i]=Sbox[j];
+ Sbox[j]=temp;
+
+ //Get ready to create pseudo random byte for encryption lpKey
+ t=((unsigned long)Sbox[i]+(unsigned long)Sbox[j])%256U;
+
+ //get the random byte
+ //xor with the data and done
+ lpBuff[x]=(lpBuff[x]^Sbox[t]);
+ }
+}
+
+
+
+#endif // !defined(AFX_RC4__H__INCLUDED_)
+
+
diff --git a/protocols/MRA/Sdk/SHA1.h b/protocols/MRA/Sdk/SHA1.h
new file mode 100644
index 0000000000..9a35d78c85
--- /dev/null
+++ b/protocols/MRA/Sdk/SHA1.h
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#if !defined(AFX__SHA1_H__INCLUDED_)
+#define AFX__SHA1_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+// see
+// RFC 3174 - SHA1
+// RFC 2104 - HMAC
+// RFC 2617 - CvtHex
+
+
+
+#define SHA1HashSize 20
+#define SHA1HashHexSize 40
+
+/* This structure will hold context information for the SHA-1 hashing operation */
+typedef struct SHA1Context
+{
+ DWORD Intermediate_Hash[SHA1HashSize/4];/* Message Digest */
+ ULARGE_INTEGER Length; /* Message length in bits */
+ BYTE Message_Block[64]; /* 512-bit message blocks */
+ BOOL Computed; /* Is the digest computed? */
+} SHA1Context;
+
+
+#ifdef UNICODE
+ #define SHA1HMACGetString SHA1HMACGetStringW
+ #define SHA1GetStringDigest SHA1GetStringDigestW
+ #define SHA1CvtString SHA1CvtStringW
+#else
+ #define SHA1HMACGetString SHA1HMACGetStringA
+ #define SHA1GetStringDigest SHA1GetStringDigestA
+ #define SHA1CvtString SHA1CvtStringA
+#endif
+
+
+#ifndef SHA1_MAX_SPEED
+ #ifdef SecureZeroMemory
+ #define SHA1SecureZeroMemory SecureZeroMemory
+ #else
+ #define SHA1SecureZeroMemory bzero
+ #endif
+#else
+ #define SHA1SecureZeroMemory
+#endif
+
+
+/*
+ * Description:
+ * This file implements the Secure Hashing Algorithm 1 as
+ * defined in FIPS PUB 180-1 published April 17, 1995.
+ *
+ * The SHA-1, produces a 160-bit message digest for a given
+ * data stream. It should take about 2**n steps to find a
+ * message with the same digest as a given message and
+ * 2**(n/2) to find any two messages with the same digest,
+ * when n is the digest size in bits. Therefore, this
+ * algorithm can serve as a means of providing a
+ * "fingerprint" for a message.
+ *
+ * Portability Issues:
+ * SHA-1 is defined in terms of 32-bit "words". This code
+ * uses <stdint.h> (included via "sha1.h" to define 32 and 8
+ * bit unsigned integer types. If your C compiler does not
+ * support 32 bit unsigned integers, this code is not
+ * appropriate.
+ *
+ * Caveats:
+ * SHA-1 is designed to work with messages less than 2^64 bits
+ * long. Although SHA-1 allows a message digest to be generated
+ * for messages of any number of bits less than 2^64, this
+ * implementation only works with messages with a length that is
+ * a multiple of the size of an 8-bit character.
+ *
+ */
+
+
+
+/* Define the SHA1 circular left shift macro */
+#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/* Local Function Prototyptes */
+//void SHA1PadMessage(SHA1Context *);
+//void SHA1ProcessMessageBlock(SHA1Context *);
+
+
+__inline DWORD BSWAP(DWORD dwIn)
+{
+return((((dwIn<<8) & 0x00ff0000) | (dwIn<<24) | ((dwIn>>8) & 0x0000ff00) | (dwIn>>24)));
+}
+
+__inline void CopyMemoryReverseDWORD(LPCVOID lpcDestination,LPCVOID lpcSource,SIZE_T dwSize)
+{
+#ifdef _WIN64
+ BYTE *pDestination=(BYTE*)lpcDestination,*pSource=(BYTE*)lpcSource;
+
+ //for(SIZE_T i=0;i<dwSize;i++) pDestination[i]=pSource[(i&~0x00000003)+(3-(i&0x00000003))];
+ for(SIZE_T i=0;i<dwSize;i+=4) (*((DWORD*)(pDestination+i)))=BSWAP((*((DWORD*)(pSource+i))));
+
+#else
+ __asm{
+ push edi // сохраняем регистр
+ push esi // сохраняем регистр
+
+ mov ecx,dwSize // ecx = длинна входного буффера
+ mov edi,lpcDestination // edi = адрес выходного буффера
+ mov esi,lpcSource // esi = указатель на входной буффер
+ cld
+
+ read_loop:
+ lodsd // читаем 4 байта
+ bswap eax
+ stosd
+ sub ecx,4
+ jg short read_loop // если длинна 3 и более байт, то продолжаем дальше
+
+ pop esi // восстанавливаем содержимое регистра
+ pop edi // восстанавливаем содержимое регистра
+ }
+#endif
+}
+
+
+
+/*
+* SHA1ProcessMessageBlock
+*
+* Description:
+* This function will process the next 512 bits of the message
+* stored in the Message_Block array.
+*
+* Parameters:
+* None.
+*
+* Returns:
+* Nothing.
+*
+* Comments:
+* Many of the variable names in this code, especially the
+* single character names, were used because those were the
+* names used in the publication.
+*
+*
+*/
+__inline void SHA1ProcessMessageBlock(SHA1Context *context,BYTE *Message_Block)
+{
+ /* Constants defined in SHA-1 */
+ const DWORD K[]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};
+ DWORD t; /* Loop counter */
+ DWORD temp; /* Temporary word value */
+ DWORD W[80]; /* Word sequence */
+ DWORD A=context->Intermediate_Hash[0],/* Word buffers */
+ B=context->Intermediate_Hash[1],
+ C=context->Intermediate_Hash[2],
+ D=context->Intermediate_Hash[3],
+ E=context->Intermediate_Hash[4];
+
+ /* Initialize the first 16 words in the array W */
+ CopyMemoryReverseDWORD(W,Message_Block,64);
+
+ for(t=16;t<80;t++)
+ {
+ W[t]=SHA1CircularShift(1,W[t-3]^W[t-8]^W[t-14]^W[t-16]);
+ }
+
+ for(t=0;t<20;t++)
+ {
+ temp=SHA1CircularShift(5,A) + ((B&C) | ((~B)&D)) + E + W[t] + K[0];
+ E=D;
+ D=C;
+ C=SHA1CircularShift(30,B);
+ B=A;
+ A=temp;
+ }
+
+ for(t=20;t<40;t++)
+ {
+ temp=SHA1CircularShift(5,A) + (B^C^D) + E + W[t] + K[1];
+ E=D;
+ D=C;
+ C=SHA1CircularShift(30,B);
+ B=A;
+ A=temp;
+ }
+
+ for(t=40;t<60;t++)
+ {
+ temp=SHA1CircularShift(5,A) + ((B&C) | (B&D) | (C&D)) + E + W[t] + K[2];
+ E=D;
+ D=C;
+ C=SHA1CircularShift(30,B);
+ B=A;
+ A=temp;
+ }
+
+ for(t=60;t<80;t++)
+ {
+ temp=SHA1CircularShift(5,A) + (B^C^D) + E + W[t] + K[3];
+ E=D;
+ D=C;
+ C=SHA1CircularShift(30,B);
+ B=A;
+ A=temp;
+ }
+
+ context->Intermediate_Hash[0]+=A;
+ context->Intermediate_Hash[1]+=B;
+ context->Intermediate_Hash[2]+=C;
+ context->Intermediate_Hash[3]+=D;
+ context->Intermediate_Hash[4]+=E;
+
+ /* Zeroize sensitive information.*/
+ SHA1SecureZeroMemory(W,sizeof(W));
+}
+
+
+/*
+* SHA1PadMessage
+*
+* Description:
+* According to the standard, the message must be padded to an even
+* 512 bits. The first padding bit must be a '1'. The last 64
+* bits represent the length of the original message. All bits in
+* between should be 0. This function will pad the message
+* according to those rules by filling the Message_Block array
+* accordingly. It will also call the ProcessMessageBlock function
+* provided appropriately. When it returns, it can be assumed that
+* the message digest has been computed.
+*
+* Parameters:
+* context: [in/out]
+* The context to pad
+* ProcessMessageBlock: [in]
+* The appropriate SHA*ProcessMessageBlock function
+* Returns:
+* Nothing.
+*
+*/
+__inline void SHA1PadMessage(SHA1Context *context)
+{
+ /*
+ * Check to see if the current message block is too small to hold
+ * the initial padding bits and length. If so, we will pad the
+ * block, process it, and then continue padding into a second
+ * block.
+ */
+ SIZE_T Message_Block_Index=(SIZE_T)((context->Length.LowPart>>3) & 0x3F);
+ context->Message_Block[Message_Block_Index++]=0x80;
+ if (Message_Block_Index>56)
+ {
+ memset(&context->Message_Block[Message_Block_Index], 0, (64-Message_Block_Index));
+ SHA1ProcessMessageBlock(context,context->Message_Block);
+ memset(&context->Message_Block, 0, 56);
+ }else{
+ memset(&context->Message_Block[Message_Block_Index], 0, (56-Message_Block_Index));
+ }
+
+ /* Store the message length as the last 8 octets */
+ context->Message_Block[56]=(BYTE)(context->Length.HighPart>>24);
+ context->Message_Block[57]=(BYTE)(context->Length.HighPart>>16);
+ context->Message_Block[58]=(BYTE)(context->Length.HighPart>>8);
+ context->Message_Block[59]=(BYTE)(context->Length.HighPart);
+ context->Message_Block[60]=(BYTE)(context->Length.LowPart>>24);
+ context->Message_Block[61]=(BYTE)(context->Length.LowPart>>16);
+ context->Message_Block[62]=(BYTE)(context->Length.LowPart>>8);
+ context->Message_Block[63]=(BYTE)(context->Length.LowPart);
+
+ SHA1ProcessMessageBlock(context,context->Message_Block);
+}
+
+
+
+/*
+* SHA1Reset
+*
+* Description:
+* This function will initialize the SHA1Context in preparation
+* for computing a new SHA1 message digest.
+*
+* Parameters:
+* context: [in/out]
+* The context to reset.
+*
+* Returns:
+* sha Error Code.
+*
+*/
+__inline DWORD SHA1Reset(SHA1Context *context)
+{
+ context->Intermediate_Hash[0]=0x67452301;
+ context->Intermediate_Hash[1]=0xEFCDAB89;
+ context->Intermediate_Hash[2]=0x98BADCFE;
+ context->Intermediate_Hash[3]=0x10325476;
+ context->Intermediate_Hash[4]=0xC3D2E1F0;
+ context->Length.QuadPart=0;
+ context->Computed=FALSE;
+
+return(NO_ERROR);
+}
+
+/*
+* SHA1Result
+*
+* Description:
+* This function will return the 160-bit message digest into the
+* Message_Digest array provided by the caller.
+* NOTE: The first octet of hash is stored in the 0th element,
+* the last octet of hash in the 19th element.
+*
+* Parameters:
+* context: [in/out]
+* The context to use to calculate the SHA-1 hash.
+* Message_Digest: [out]
+* Where the digest is returned.
+*
+* Returns:
+* sha Error Code.
+*
+*/
+__inline DWORD SHA1Result(SHA1Context *context,BYTE *Message_Digest)
+{
+ if (context->Computed==FALSE)
+ {
+ SHA1PadMessage(context);
+ SHA1SecureZeroMemory(context->Message_Block,64);/* message may be sensitive, clear it out */
+ context->Length.QuadPart=0; /* and clear length */
+ context->Computed=TRUE;
+ }
+
+ CopyMemoryReverseDWORD(Message_Digest,context->Intermediate_Hash,SHA1HashSize);
+
+return(NO_ERROR);
+}
+
+/*
+* SHA1Input
+*
+* Description:
+* This function accepts an array of octets as the next portion
+* of the message.
+*
+* Parameters:
+* context: [in/out]
+* The SHA context to update
+* message_array: [in]
+* An array of characters representing the next portion of
+* the message.
+* length: [in]
+* The length of the message in message_array
+*
+* Returns:
+* sha Error Code.
+*
+*/
+__inline DWORD SHA1Input(SHA1Context *context,const BYTE *message_array,SIZE_T length)
+{
+ if (context->Computed==TRUE) return(ERROR_INVALID_HANDLE_STATE);
+
+ if ((context->Length.QuadPart+(length<<3))>=(length<<3))
+ {
+ SIZE_T i,Message_Block_Index,partLen;
+ /* Compute number of bytes mod 64 */
+ Message_Block_Index=(SIZE_T)((context->Length.LowPart>>3) & 0x3F);
+ /* Update number of bits */
+ context->Length.QuadPart+=(((ULONGLONG)length)<<3);
+ partLen=(64-Message_Block_Index);
+ /* Transform as many times as possible.*/
+ if (length>=partLen)
+ {
+ memmove(&context->Message_Block[Message_Block_Index],message_array,partLen);
+ SHA1ProcessMessageBlock(context,context->Message_Block);
+ for (i=partLen;(i+63)<length;i+=64) SHA1ProcessMessageBlock(context,(BYTE*)&message_array[i]);
+ Message_Block_Index=0;
+ }else{
+ i=0;
+ }
+ /* Buffer remaining input */
+ memmove(&context->Message_Block[Message_Block_Index],&message_array[i],(length-i));
+ }else{
+ return(RPC_S_STRING_TOO_LONG);/* Message is too long */
+ }
+return(NO_ERROR);
+}
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+//////////////////////////////RFC 2104//////////////////////////////
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+__inline void hmac_sha1(BYTE *text,SIZE_T text_len,BYTE *key,SIZE_T key_len,BYTE *digest)
+{
+//BYTE* text; /* pointer to data stream */
+//int text_len; /* length of data stream */
+//BYTE* key; /* pointer to authentication key */
+//int key_len; /* length of authentication key */
+//HASH digest; /* caller digest to be filled in */
+ SHA1Context context;
+ BYTE k_ipad[65]; /* inner padding - key XORd with ipad */
+ BYTE k_opad[65]; /* outer padding - key XORd with opad */
+ BYTE tk[SHA1HashSize];
+ /* if key is longer than 64 bytes reset it to key=SHA1(key) */
+ if (key_len>64)
+ {
+ SHA1Context tctx;
+
+ SHA1Reset(&tctx);
+ SHA1Input(&tctx,key,key_len);
+ SHA1Result(&tctx,(BYTE*)&tk);
+
+ key=tk;
+ key_len=SHA1HashSize;
+ }
+
+ /*
+ * the HMAC_SHA1 transform looks like:
+ *
+ * SHA1(K XOR opad, SHA1(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ */
+
+ /* start out by storing key in pads */
+ memmove(&k_ipad,key,key_len);
+ memmove(&k_opad,key,key_len);
+ memset(&k_ipad[key_len], 0, (sizeof(k_ipad)-key_len));
+ memset(&k_opad[key_len], 0 , (sizeof(k_opad)-key_len));
+
+ /* XOR key with ipad and opad values */
+ for (SIZE_T i=0;i<(64/sizeof(ULONGLONG));i++)
+ {
+ ((ULONGLONG*)k_ipad)[i]^=0x3636363636363636;
+ ((ULONGLONG*)k_opad)[i]^=0x5C5C5C5C5C5C5C5C;
+ }
+ /* perform inner SHA1 */
+ SHA1Reset(&context); /* init context for 1st pass */
+ SHA1Input(&context,k_ipad,64); /* start with inner pad */
+ SHA1Input(&context,text,text_len); /* then text of datagram */
+ SHA1Result(&context,digest); /* finish up 1st pass */
+ /* perform outer SHA1 */
+ SHA1Reset(&context); /* init context for 2nd pass */
+ SHA1Input(&context,k_opad,64); /* start with outer pad */
+ SHA1Input(&context,(BYTE*)digest,SHA1HashSize); /* then results of 1st hash */
+ SHA1Result(&context,digest); /* finish up 2nd pass */
+
+ SHA1SecureZeroMemory(k_ipad,sizeof(k_ipad));
+ SHA1SecureZeroMemory(k_opad,sizeof(k_opad));
+ SHA1SecureZeroMemory(tk,sizeof(tk));
+}
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+//////////////////////////////RFC 2617//////////////////////////////
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+__inline void SHA1CvtHex(BYTE *Bin,BYTE *Hex)
+{
+ BYTE j;
+
+ for (SIZE_T i=0;i<SHA1HashSize;i++)
+ {
+ j=(Bin[i]>>4)&0xf;
+ if(j<=9)
+ {
+ Hex[(i*2)]=(j+'0');
+ }else{
+ Hex[(i*2)]=(j+'a'-10);
+ }
+
+ j=Bin[i]&0xf;
+ if(j<=9)
+ {
+ Hex[(i*2+1)]=(j+'0');
+ }else{
+ Hex[(i*2+1)]=(j+'a'-10);
+ }
+ };
+ Hex[SHA1HashHexSize]=0;
+};
+
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+__inline void SHA1CvtStringA(BYTE *digest,LPSTR lpszDigest)
+{
+ SHA1CvtHex(digest,(BYTE*)lpszDigest);
+};
+
+
+__inline void SHA1CvtStringW(BYTE *digest,LPWSTR lpszDigest)
+{
+ SIZE_T i,p=0;
+ for (i=0;i<SHA1HashSize;i++,p+=2)
+ {
+ wsprintfW((LPWSTR)(lpszDigest+p),L"%02x",digest[i]);
+ }
+ lpszDigest[SHA1HashHexSize]=0;
+};
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+__inline void SHA1HMACGetDigest(LPVOID lpBuff,SIZE_T dwBuffSize,LPVOID lpKey,SIZE_T dwKeySize,BYTE *digest)
+{
+ hmac_sha1((BYTE*)lpBuff,dwBuffSize,(BYTE*)lpKey,dwKeySize,digest);
+}
+
+
+__inline void SHA1HMACGetStringA(LPSTR lpszBuff,SIZE_T dwBuffSize,LPSTR lpszKey,SIZE_T dwKeySize,LPSTR lpszDigest)
+{
+ BYTE digest[SHA1HashSize];
+ hmac_sha1((BYTE*)lpszBuff,dwBuffSize,(BYTE*)lpszKey,dwKeySize,digest);
+ SHA1CvtHex(digest,(BYTE*)lpszDigest);
+}
+
+
+__inline void SHA1HMACGetStringW(LPWSTR lpszBuff,SIZE_T dwBuffSize,LPWSTR lpszKey,SIZE_T dwKeySize,LPWSTR lpszDigest)
+{
+ BYTE digest[SHA1HashSize];
+ hmac_sha1((BYTE*)lpszBuff,dwBuffSize,(BYTE*)lpszKey,dwKeySize,digest);
+ SHA1CvtStringW(digest,lpszDigest);
+}
+
+
+
+__inline void SHA1GetDigest(LPVOID lpBuff,SIZE_T dwBuffSize,BYTE *digest)
+{
+ SHA1Context sha;
+
+ SHA1Reset(&sha);
+ SHA1Input(&sha,(BYTE*)lpBuff,dwBuffSize);
+ SHA1Result(&sha,digest);
+}
+
+
+__inline void SHA1GetStringDigestA(LPSTR lpszBuff,SIZE_T dwBuffSize,LPSTR lpszDigest)
+{
+ SHA1Context sha;
+ BYTE digest[SHA1HashSize];
+
+ SHA1Reset(&sha);
+ SHA1Input(&sha,(BYTE*)lpszBuff,dwBuffSize);
+ SHA1Result(&sha,digest);
+
+ SHA1CvtHex(digest,(BYTE*)lpszDigest);
+}
+
+
+__inline void SHA1GetStringDigestW(LPWSTR lpszBuff,SIZE_T dwBuffSize,LPWSTR lpszDigest)
+{
+ SHA1Context sha;
+ BYTE digest[SHA1HashSize];
+
+ SHA1Reset(&sha);
+ SHA1Input(&sha,(BYTE*)lpszBuff,dwBuffSize);
+ SHA1Result(&sha,digest);
+
+ SHA1CvtStringW(digest,lpszDigest);
+}
+
+
+
+
+#endif //AFX__SHA1_H__INCLUDED_ \ No newline at end of file
diff --git a/protocols/MRA/Sdk/SocketFunctions.h b/protocols/MRA/Sdk/SocketFunctions.h
new file mode 100644
index 0000000000..480b5beccb
--- /dev/null
+++ b/protocols/MRA/Sdk/SocketFunctions.h
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_SOCKET_FUNCTIONS__H__INCLUDED_)
+#define AFX_SOCKET_FUNCTIONS__H__INCLUDED_
+
+#if(_WIN32_WINNT >= 0x0501)
+static LPFN_CONNECTEX ConnectEx=NULL;
+static LPFN_DISCONNECTEX DisconnectEx=NULL;
+static LPFN_TRANSMITPACKETS TransmitPackets=NULL;
+#endif
+
+
+#ifndef NTOHS
+
+__inline u_short USHORT_FLIP(u_short usIn)
+{
+return(((usIn<<8) | (usIn>>8)));
+}
+#define NTOHS(in) USHORT_FLIP(in)
+#define HTONS(in) USHORT_FLIP(in)
+
+#endif
+
+
+
+#ifndef NTOHL
+
+__inline u_long ULONG_FLIP(u_long ulIn)
+{
+#if defined (_M_IA64) || defined (_M_AMD64)
+return((((ulIn<<8) & 0x00ff0000) | (ulIn<<24) | ((ulIn>>8) & 0x0000ff00) | (ulIn>>24)));
+#else
+ __asm
+ {
+ mov eax,ulIn
+ bswap eax
+ mov ulIn,eax
+ };
+return(ulIn);
+#endif
+}
+
+#define NTOHL(in) ULONG_FLIP(in)
+#define HTONL(in) ULONG_FLIP(in)
+
+#endif
+
+
+
+
+
+#define CLOSE_SOCKET(skt) if (skt) {closesocket(skt);skt=INVALID_SOCKET;}
+
+
+
+__inline BOOL SocketGetACCEPTCONN(SOCKET skt)
+{
+ BOOL bRet;
+ int iSize=sizeof(BOOL);
+ if (getsockopt(skt,SOL_SOCKET,SO_ACCEPTCONN,(char*)&bRet,(int*)&iSize)!=NO_ERROR) bRet=FALSE;
+return(bRet);
+}
+
+
+__inline BOOL SocketGetBROADCAST(SOCKET skt)
+{
+ BOOL bRet;
+ int iSize=sizeof(BOOL);
+ if (getsockopt(skt,SOL_SOCKET,SO_BROADCAST,(char*)&bRet,(int*)&iSize)!=NO_ERROR) bRet=FALSE;
+return(bRet);
+}
+
+__inline int SocketSetBROADCAST(SOCKET skt,BOOL bBroadcast)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL)));
+}
+
+
+
+__inline int SocketGetCONNECT_TIME(SOCKET skt)
+{
+ int iSeconds,iSize=sizeof(int);
+ if (getsockopt(skt,SOL_SOCKET,SO_CONNECT_TIME,(char*)&iSeconds,(int*)&iSize)!=NO_ERROR) iSeconds=-1;
+return(iSeconds);
+}
+
+
+__inline BOOL SocketGetKEEPALIVE(SOCKET skt)
+{
+ BOOL bRet;
+ int iSize=sizeof(BOOL);
+ if (getsockopt(skt,SOL_SOCKET,SO_KEEPALIVE,(char*)&bRet,(int*)&iSize)!=NO_ERROR) bRet=FALSE;
+return(bRet);
+}
+
+__inline int SocketSetKEEPALIVE(SOCKET skt,BOOL bKeepAlive)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_KEEPALIVE,(const char*)&bKeepAlive,sizeof(BOOL)));
+}
+
+
+
+__inline int SocketGetMAX_MSG_SIZE(SOCKET skt)
+{
+ int iMaxMsgSize,iSize=sizeof(int);
+ if (getsockopt(skt,SOL_SOCKET,SO_MAX_MSG_SIZE,(char*)&iMaxMsgSize,(int*)&iSize)!=NO_ERROR) iMaxMsgSize=-1;
+return(iMaxMsgSize);
+}
+
+
+__inline int SocketSetEXCLUSIVEADDRUSE(SOCKET skt,BOOL bExclusiveAddrUse)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_EXCLUSIVEADDRUSE,(const char*)&bExclusiveAddrUse,sizeof(BOOL)));
+}
+
+
+__inline BOOL SocketGetREUSEADDR(SOCKET skt)
+{
+ BOOL bRet;
+ int iSize=sizeof(BOOL);
+ if (getsockopt(skt,SOL_SOCKET,SO_REUSEADDR,(char*)&bRet,(int*)&iSize)!=NO_ERROR) bRet=FALSE;
+return(bRet);
+}
+
+__inline int SocketSetREUSEADDR(SOCKET skt,BOOL bReuseAddr)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_REUSEADDR,(const char*)&bReuseAddr,sizeof(BOOL)));
+}
+
+
+__inline int SocketSetRCVBUF(SOCKET skt,unsigned int uiBuffSize)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_RCVBUF,(const char*)&uiBuffSize,sizeof(int)));
+}
+
+
+__inline int SocketSetSNDBUF(SOCKET skt,unsigned int uiBuffSize)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_SNDBUF,(const char*)&uiBuffSize,sizeof(int)));
+}
+
+
+
+__inline int SocketSetUPDATE_ACCEPT_CONTEXT(SOCKET skt,SOCKET sktAccept)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_UPDATE_ACCEPT_CONTEXT,(char*)&sktAccept,sizeof(SOCKET)));
+}
+
+
+#if(_WIN32_WINNT >= 0x0501)
+__inline int SocketSetUPDATE_CONNECT_CONTEXT(SOCKET skt)
+{
+return(setsockopt(skt,SOL_SOCKET,SO_UPDATE_CONNECT_CONTEXT,NULL,0));
+}
+#endif
+
+
+
+
+__inline BOOL SocketGetHDRINCL(SOCKET skt)
+{
+ BOOL bRet;
+ int iSize=sizeof(BOOL);
+ if (getsockopt(skt,IPPROTO_IP,IP_HDRINCL,(char*)&bRet,(int*)&iSize)!=NO_ERROR) bRet=FALSE;
+return(bRet);
+}
+
+__inline int SocketSetHDRINCL(SOCKET skt,BOOL bProvideIPHdr)
+{
+return(setsockopt(skt,IPPROTO_IP,IP_HDRINCL,(const char*)&bProvideIPHdr,sizeof(DWORD)));
+}
+
+
+#define TOS_DEFAULT 0
+#define TOS_MIN_MONETARY_COST 2
+#define TOS_MIN_RELIABILITY 4
+#define TOS_MAX_THROUGHPUT 8
+#define TOS_MIN_DELAY 16
+#define TOS_MAX_SECURITY 30
+
+__inline int SocketSetTOS(SOCKET skt,DWORD dwTOS)
+{
+return(setsockopt(skt,IPPROTO_IP,IP_TOS,(const char*)&dwTOS,sizeof(DWORD)));
+}
+
+
+__inline int SocketSetTTL(SOCKET skt,UINT iTTL)
+{
+return(setsockopt(skt,IPPROTO_IP,IP_TTL,(const char*)&iTTL,sizeof(DWORD)));
+}
+
+
+__inline int SocketSetTCP_NODELAY(SOCKET skt,BOOL bTCPNoDelay)
+{
+return(setsockopt(skt,IPPROTO_TCP,TCP_NODELAY,(const char*)&bTCPNoDelay,sizeof(DWORD)));
+}
+
+/*
+int // OUT: whatever setsockopt() returns
+join_source_group(int sd, u_int32 grpaddr,
+ u_int32 srcaddr, u_int32 iaddr)
+{
+ struct ip_mreq_source imr;
+
+ imr.imr_multiaddr.s_addr = grpaddr;
+ imr.imr_sourceaddr.s_addr = srcaddr;
+ imr.imr_interface.s_addr = iaddr;
+ return setsockopt(sd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, &imr, sizeof(imr));
+}
+
+int
+leave_source_group(int sd, u_int32 grpaddr,
+ u_int32 srcaddr, u_int32 iaddr)
+{
+ struct ip_mreq_source imr;
+
+ imr.imr_multiaddr.s_addr = grpaddr;
+ imr.imr_sourceaddr.s_addr = srcaddr;
+ imr.imr_interface.s_addr = iaddr;
+ return setsockopt(sd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, &imr, sizeof(imr));
+}*/
+
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+__inline BOOL WINAPI DisconnectExTF(SOCKET hSocket,LPOVERLAPPED lpOverlapped,DWORD dwFlags,DWORD reserved)
+{
+ reserved=0;
+ dwFlags&=TF_REUSE_SOCKET;
+ dwFlags|=TF_DISCONNECT;
+return(TransmitFile(hSocket,NULL,0,0,lpOverlapped,NULL,dwFlags));
+}
+
+
+
+__inline DWORD SocketsInitialize()
+{
+ DWORD dwRetErrorCode;
+ WSADATA wsaData;
+
+ if ((dwRetErrorCode=WSAStartup(MAKEWORD(1,1),&wsaData))==NO_ERROR)
+ {// version 1.1 OK
+ WSACleanup();
+
+ dwRetErrorCode=WSAStartup(wsaData.wHighVersion,&wsaData);
+ }
+return(dwRetErrorCode);
+}
+
+
+#if(_WIN32_WINNT >= 0x0501)
+__inline DWORD SocketsInitializeEx(DWORD dwFlags)
+{
+ DWORD dwRetErrorCode;
+ WSADATA wsaData;
+
+ dwFlags=0;
+ if ((dwRetErrorCode=WSAStartup(MAKEWORD(1,1),&wsaData))==NO_ERROR)
+ {// version 1.1 OK
+ WSACleanup();
+ if ((dwRetErrorCode=WSAStartup(wsaData.wHighVersion,&wsaData))==NO_ERROR)
+ {// max version initialized
+ SOCKET skt;
+
+ if ((skt=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,WSA_FLAG_OVERLAPPED))!=INVALID_SOCKET)
+ {
+ DWORD dwSize;
+ GUID ExtensionGuidCONNECTEX=WSAID_CONNECTEX;
+ GUID ExtensionGuidDISCONNECTEX=WSAID_DISCONNECTEX;
+ GUID ExtensionGuidTRANSMITPACKETS=WSAID_TRANSMITPACKETS;
+
+ dwRetErrorCode=NO_ERROR;
+
+ if (WSAIoctl(skt,SIO_GET_EXTENSION_FUNCTION_POINTER,&ExtensionGuidCONNECTEX,sizeof(GUID),&ConnectEx,sizeof(FARPROC),&dwSize,NULL,NULL)==0)
+ {
+ if (ConnectEx==NULL) dwRetErrorCode=WSAGetLastError();
+ }else{
+ dwRetErrorCode=WSAGetLastError();
+ }
+
+
+ if (WSAIoctl(skt,SIO_GET_EXTENSION_FUNCTION_POINTER,&ExtensionGuidDISCONNECTEX,sizeof(GUID),&DisconnectEx,sizeof(FARPROC),&dwSize,NULL,NULL)==0)
+ {
+ if (DisconnectEx==NULL)
+ {
+ DisconnectEx=DisconnectExTF;
+ //dwRetErrorCode=WSAGetLastError();
+ }
+ }else{
+ dwRetErrorCode=WSAGetLastError();
+ }
+
+ if (WSAIoctl(skt,SIO_GET_EXTENSION_FUNCTION_POINTER,&ExtensionGuidTRANSMITPACKETS,sizeof(GUID),&TransmitPackets,sizeof(FARPROC),&dwSize,NULL,NULL)==0)
+ {
+ if (TransmitPackets==NULL) dwRetErrorCode=WSAGetLastError();
+ }else{
+ dwRetErrorCode=WSAGetLastError();
+ }
+
+ closesocket(skt);
+ }else{
+ dwRetErrorCode=WSAGetLastError();
+ }
+ }
+ }
+return(dwRetErrorCode);
+}
+#endif
+
+
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+///////////////////////////SOCKADDR_STORAGE/////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+#if(_WIN32_WINNT >= 0x0501)
+
+__inline DWORD SockAddrInDataSet(LPCVOID lpcsasSockAddrStorage,DWORD dwPort,LPCVOID lpcAddress,SIZE_T dwAddressSize)
+{
+ DWORD dwRetErrorCode=NO_ERROR;
+
+ if (lpcsasSockAddrStorage && lpcAddress)
+ {
+ switch(dwAddressSize){
+ case sizeof(in_addr):
+ ((sockaddr_in*)lpcsasSockAddrStorage)->sin_family=AF_INET;
+ ((sockaddr_in*)lpcsasSockAddrStorage)->sin_port=HTONS((WORD)dwPort);
+ (*((DWORD*)&(((sockaddr_in*)lpcsasSockAddrStorage)->sin_addr)))=(*((DWORD*)lpcAddress));
+ break;
+ case sizeof(in6_addr):
+ ((sockaddr_in6*)lpcsasSockAddrStorage)->sin6_family=AF_INET6;
+ ((sockaddr_in6*)lpcsasSockAddrStorage)->sin6_port=HTONS((WORD)dwPort);
+ memmove(&(((sockaddr_in6*)lpcsasSockAddrStorage)->sin6_addr),lpcAddress,sizeof(in6_addr));
+ break;
+ default:
+ dwRetErrorCode=ERROR_INVALID_PARAMETER;
+ break;
+ }
+ }else{
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD SockAddrInPortSet(LPCVOID lpcsasSockAddrStorage,DWORD dwPort)
+{
+ DWORD dwRetErrorCode=NO_ERROR;
+
+ if (lpcsasSockAddrStorage)
+ {
+ switch(((SOCKADDR_STORAGE*)lpcsasSockAddrStorage)->ss_family){
+ case AF_INET:
+ ((sockaddr_in*)lpcsasSockAddrStorage)->sin_port=HTONS((WORD)dwPort);
+ break;
+ case AF_INET6:
+ ((sockaddr_in6*)lpcsasSockAddrStorage)->sin6_port=HTONS((WORD)dwPort);
+ break;
+ default:
+ dwRetErrorCode=ERROR_INVALID_PARAMETER;
+ break;
+ }
+ }else{
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD SockAddrInAddressSet(LPCVOID lpcsasSockAddrStorage,LPCVOID lpcAddress,SIZE_T dwAddressSize)
+{
+ DWORD dwRetErrorCode=NO_ERROR;
+
+ if (lpcsasSockAddrStorage && lpcAddress)
+ {
+ switch(dwAddressSize){
+ case sizeof(in_addr):
+ ((sockaddr_in*)lpcsasSockAddrStorage)->sin_family=AF_INET;
+ (*((DWORD*)&(((sockaddr_in*)lpcsasSockAddrStorage)->sin_addr)))=(*((DWORD*)lpcAddress));
+ break;
+ case sizeof(in6_addr):
+ ((sockaddr_in6*)lpcsasSockAddrStorage)->sin6_family=AF_INET6;
+ memmove(&(((sockaddr_in6*)lpcsasSockAddrStorage)->sin6_addr),lpcAddress,sizeof(in6_addr));
+ break;
+ default:
+ dwRetErrorCode=ERROR_INVALID_PARAMETER;
+ break;
+ }
+ }else{
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD SockAddrAddressSet(LPCVOID lpcsasSockAddrStorage,LPCVOID lpcAddress,SIZE_T dwAddressSize)
+{
+ DWORD dwRetErrorCode=NO_ERROR;
+
+ if (lpcsasSockAddrStorage && lpcAddress)
+ {
+ switch(dwAddressSize){
+ case sizeof(in_addr):
+ ((sockaddr*)lpcsasSockAddrStorage)->sa_family=AF_INET;
+ (*((DWORD*)&(((sockaddr*)lpcsasSockAddrStorage)->sa_data)))=(*((DWORD*)lpcAddress));
+ break;
+ case sizeof(in6_addr):
+ ((sockaddr*)lpcsasSockAddrStorage)->sa_family=AF_INET6;
+ memmove(&(((sockaddr*)lpcsasSockAddrStorage)->sa_data),lpcAddress,sizeof(in6_addr));
+ break;
+ default:
+ dwRetErrorCode=ERROR_INVALID_PARAMETER;
+ break;
+ }
+ }else{
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline SIZE_T SockAddrGetSize(LPCVOID lpcsasSockAddrStorage)
+{
+ SIZE_T dwRet;
+
+ if (lpcsasSockAddrStorage)
+ {
+ switch(((SOCKADDR_STORAGE*)lpcsasSockAddrStorage)->ss_family){
+ case AF_INET:
+ dwRet=sizeof(sockaddr_in);
+ break;
+ case AF_INET6:
+ dwRet=sizeof(sockaddr_in6);
+ break;
+ default:
+ dwRet=sizeof(SOCKADDR_STORAGE);
+ break;
+ }
+ }else{
+ dwRet=0;
+ }
+return(dwRet);
+}
+
+
+#endif
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+#endif //AFX_SOCKET_FUNCTIONS__H__INCLUDED_ \ No newline at end of file
diff --git a/protocols/MRA/Sdk/StrHexToNum.h b/protocols/MRA/Sdk/StrHexToNum.h
new file mode 100644
index 0000000000..60b5801efb
--- /dev/null
+++ b/protocols/MRA/Sdk/StrHexToNum.h
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2005 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_STRHEXTONUM__H__INCLUDED_)
+#define AFX_STRHEXTONUM__H__INCLUDED_
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+
+__inline SIZE_T StrHexToUNum(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ SIZE_T dwNum=0;
+ BYTE bCurentFigure;
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ dwNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+return(dwNum);
+}
+
+__inline DWORD StrHexToUNum32(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ DWORD dwNum=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ dwNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+return(dwNum);
+}
+
+__inline DWORDLONG StrHexToUNum64(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ DWORDLONG dwlNum=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ dwlNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwlNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+return(dwlNum);
+}
+
+
+
+__inline DWORD StrHexToUNumEx(LPCSTR lpcszString,SIZE_T dwStringLen,SIZE_T *pdwNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwNum=0,dwProcessed=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ dwNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pdwNum) (*pdwNum)=dwNum;
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrHexToUNumEx32(LPCSTR lpcszString,SIZE_T dwStringLen,DWORD *pdwNum)
+{
+ DWORD dwRetErrorCode;
+ DWORD dwNum=0,dwProcessed=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ dwNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pdwNum) (*pdwNum)=dwNum;
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrHexToUNumEx64(LPCSTR lpcszString,SIZE_T dwStringLen,DWORDLONG *pdwlNum)
+{
+ DWORD dwRetErrorCode;
+ DWORDLONG dwlNum=0;
+ SIZE_T dwProcessed=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ dwlNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwlNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pdwlNum) (*pdwlNum)=dwlNum;
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+
+__inline SSIZE_T StrHexToNum(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ SSIZE_T lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ lNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+ lNum*=lSingn;
+
+return(lNum);
+}
+
+
+__inline LONG StrHexToNum32(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ LONG lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ lNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+ lNum*=lSingn;
+
+return(lNum);
+}
+
+
+__inline LONGLONG StrHexToNum64(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ LONGLONG llNum=0,llSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') llSingn=-1;
+ if (bCurentFigure=='+') llSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ llNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ llNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+ llNum*=llSingn;
+
+return(llNum);
+}
+
+
+
+__inline DWORD StrHexToNumEx(LPCSTR lpcszString,SIZE_T dwStringLen,SSIZE_T *plNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwProcessed=0;
+ SSIZE_T lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ lNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (plNum) (*plNum)=(lNum*lSingn);
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrHexToNumEx32(LPCSTR lpcszString,SIZE_T dwStringLen,LONG *plNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwProcessed=0;
+ LONG lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ lNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (plNum) (*plNum)=(lNum*lSingn);
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrHexToNumEx64(LPCSTR lpcszString,SIZE_T dwStringLen,LONGLONG *pllNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwProcessed=0;
+ LONGLONG llNum=0,llSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') llSingn=-1;
+ if (bCurentFigure=='+') llSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ bCurentFigure=(*lpcszString);
+ if ('0'<=bCurentFigure && bCurentFigure<='9')
+ {
+ bCurentFigure-='0';
+ }else
+ if ('a'<=bCurentFigure && bCurentFigure<='f')
+ {
+ bCurentFigure-=('a'+10);
+ }else
+ if ('A'<=bCurentFigure && bCurentFigure<='F')
+ {
+ bCurentFigure-=('A'+10);
+ }else{
+ bCurentFigure=255;
+ }
+
+ if (bCurentFigure!=255)
+ {
+ llNum*=16;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ llNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pllNum) (*pllNum)=(llNum*llSingn);
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+
+#endif // !defined(AFX_STRHEXTONUM__H__INCLUDED_) \ No newline at end of file
diff --git a/protocols/MRA/Sdk/StrToNum.h b/protocols/MRA/Sdk/StrToNum.h
new file mode 100644
index 0000000000..888b940b7c
--- /dev/null
+++ b/protocols/MRA/Sdk/StrToNum.h
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2005 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_STRTONUM__H__INCLUDED_)
+#define AFX_STRTONUM__H__INCLUDED_
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+
+
+
+__inline SIZE_T StrToUNum(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ SIZE_T dwNum=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ dwNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+return(dwNum);
+}
+
+
+__inline DWORD StrToUNum32(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ DWORD dwNum=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ dwNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+return(dwNum);
+}
+
+
+__inline DWORDLONG StrToUNum64(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ DWORDLONG dwlNum=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ dwlNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwlNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+return(dwlNum);
+}
+
+
+
+
+__inline DWORD StrToUNumEx(LPCSTR lpcszString,SIZE_T dwStringLen,SIZE_T *pdwNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwNum=0,dwProcessed=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ dwNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pdwNum) (*pdwNum)=dwNum;
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrToUNumEx32(LPCSTR lpcszString,SIZE_T dwStringLen,DWORD *pdwNum)
+{
+ DWORD dwRetErrorCode;
+ DWORD dwNum=0,dwProcessed=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ dwNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pdwNum) (*pdwNum)=dwNum;
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrToUNumEx64(LPCSTR lpcszString,SIZE_T dwStringLen,DWORDLONG *pdwlNum)
+{
+ DWORD dwRetErrorCode;
+ DWORDLONG dwlNum=0;
+ SIZE_T dwProcessed=0;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ dwlNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ dwlNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pdwlNum) (*pdwlNum)=dwlNum;
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+
+__inline SSIZE_T StrToNum(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ SSIZE_T lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ lNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+ lNum*=lSingn;
+
+return(lNum);
+}
+
+
+__inline LONG StrToNum32(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ LONG lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ lNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+ lNum*=lSingn;
+
+return(lNum);
+}
+
+
+__inline LONGLONG StrToNum64(LPCSTR lpcszString,SIZE_T dwStringLen)
+{
+ LONGLONG llNum=0,llSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') llSingn=-1;
+ if (bCurentFigure=='+') llSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ llNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ llNum+=bCurentFigure;// добавляем цифру в младший разряд
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+ llNum*=llSingn;
+
+return(llNum);
+}
+
+
+
+__inline DWORD StrToNumEx(LPCSTR lpcszString,SIZE_T dwStringLen,SSIZE_T *plNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwProcessed=0;
+ SSIZE_T lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ lNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (plNum) (*plNum)=(lNum*lSingn);
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrToNumEx32(LPCSTR lpcszString,SIZE_T dwStringLen,LONG *plNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwProcessed=0;
+ LONG lNum=0,lSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') lSingn=-1;
+ if (bCurentFigure=='+') lSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ lNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ lNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (plNum) (*plNum)=(lNum*lSingn);
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD StrToNumEx64(LPCSTR lpcszString,SIZE_T dwStringLen,LONGLONG *pllNum)
+{
+ DWORD dwRetErrorCode;
+ SIZE_T dwProcessed=0;
+ LONGLONG llNum=0,llSingn=1;
+ BYTE bCurentFigure;
+
+
+ while(dwStringLen && ((bCurentFigure=((*lpcszString)-48))>9))
+ {
+ if (bCurentFigure=='-') llSingn=-1;
+ if (bCurentFigure=='+') llSingn=1;
+
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ while(dwStringLen)
+ {
+ if ((bCurentFigure=((*lpcszString)-48))<10)
+ {
+ llNum*=10;// сдвигаем предыдущее число на один разряд чтоб добавить в младший разряд новую цифру
+ llNum+=bCurentFigure;// добавляем цифру в младший разряд
+ dwProcessed++;// увеличиваем счётчик обработанных цифр
+ }
+ lpcszString++;// перемещаем указатель на следующую позицию
+ dwStringLen--;// уменьшаем длинну
+ }
+
+ if (dwProcessed)
+ {// как минимум одна цифра была обработана
+ if (pllNum) (*pllNum)=(llNum*llSingn);
+ if (dwProcessed==dwStringLen)
+ {// в строке были только цифры, всё отработало как нужно //Операция успешно завершена.
+ dwRetErrorCode=NO_ERROR;
+ }else{// в строке были не только цифры //Имеются дополнительные данные.
+ dwRetErrorCode=ERROR_MORE_DATA;
+ }
+ }else{// строка вообще не содержала цифр //Недопустимые данные.
+ dwRetErrorCode=ERROR_INVALID_DATA;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+
+#endif // !defined(AFX_STRTONUM__H__INCLUDED_) \ No newline at end of file
diff --git a/protocols/MRA/Sdk/timefuncs.h b/protocols/MRA/Sdk/timefuncs.h
new file mode 100644
index 0000000000..e170b0acd2
--- /dev/null
+++ b/protocols/MRA/Sdk/timefuncs.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2009 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+
+#if !defined(AFX_TIME_FUNCS__H__INCLUDED_)
+#define AFX_TIME_FUNCS__H__INCLUDED_
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <windows.h>
+#include <time.h>
+
+
+
+#define _MAX__TIME32_T 0x7fffd27f // number of seconds from
+ // 00:00:00, 01/01/1970 UTC to
+ // 23:59:59, 01/18/2038 UTC
+
+// Number of 100 nanosecond units from 1/1/1601 to 1/1/1970
+#define EPOCH_BIAS 116444736000000000i64
+
+//nion to facilitate converting from FILETIME to unsigned __int64
+typedef union {
+ unsigned __int64 ft_scalar;
+ FILETIME ft_struct;
+ } FT;
+
+
+static inline __time32_t __cdecl _time32(__time32_t *timeptr)
+{
+ __time64_t tim;
+ FT nt_time;
+
+ GetSystemTimeAsFileTime(&(nt_time.ft_struct));
+ tim=(__time64_t)((nt_time.ft_scalar-EPOCH_BIAS)/10000000i64);
+ if (tim > (__time64_t)(_MAX__TIME32_T)) tim=(__time64_t)(-1);
+ if (timeptr) *timeptr = (__time32_t)(tim);// store time if requested
+
+return(__time32_t)(tim);
+}
+
+
+inline __time32_t MakeTime32FromLocalSystemTime(CONST PSYSTEMTIME pcstSystemTime)
+{
+ __time64_t tim=0;
+ FT nt_time;
+
+ if (SystemTimeToFileTime(pcstSystemTime,&(nt_time.ft_struct)))
+ {
+ if (LocalFileTimeToFileTime(&(nt_time.ft_struct),&(nt_time.ft_struct)))
+ {
+ tim=(__time64_t)((nt_time.ft_scalar-EPOCH_BIAS)/10000000i64);
+ if (tim > (__time64_t)(_MAX__TIME32_T)) tim=(__time64_t)(-1);
+ }
+ }
+return(__time32_t)(tim);
+}
+
+
+inline BOOL MakeLocalSystemTimeFromTime32(__time32_t tim32,PSYSTEMTIME pstSystemTime)
+{
+ BOOL bRet=FALSE;
+
+ if (pstSystemTime)
+ {
+ __time64_t tim=(__time64_t)tim32;
+ FT nt_time;
+
+ //if (tim==(__time64_t)(-1)) tim=(__time64_t)(_MAX__TIME32_T);
+ nt_time.ft_scalar=(__time64_t)((tim*10000000i64)+EPOCH_BIAS);
+ if (FileTimeToLocalFileTime(&(nt_time.ft_struct),&(nt_time.ft_struct)))
+ {
+ bRet=FileTimeToSystemTime(&(nt_time.ft_struct),pstSystemTime);
+ }
+ }
+return(bRet);
+}
+
+
+
+static inline __time32_t __cdecl _mktime32(struct tm *ptmTime)
+{
+ SYSTEMTIME stTime;
+
+ stTime.wMilliseconds=0;
+ stTime.wSecond=ptmTime->tm_sec; // seconds after the minute - [0,59]
+ stTime.wMinute=ptmTime->tm_min; // minutes after the hour - [0,59]
+ stTime.wHour=ptmTime->tm_hour; // hours since midnight - [0,23]
+ stTime.wDay=ptmTime->tm_mday; // day of the month - [1,31]
+ stTime.wMonth=(ptmTime->tm_mon+1); // months since January - [0,11]
+ stTime.wYear=(ptmTime->tm_year+1900); // years since 1900
+ stTime.wDayOfWeek=0;//ptmTime->tm_wday; // days since Sunday - [0,6]
+ //ptmTime->tm_yday; // days since January 1 - [0,365]
+ //ptmTime->tm_isdst; // daylight savings time flag
+return(MakeTime32FromLocalSystemTime(&stTime));
+}
+
+
+
+
+
+#endif // !defined(AFX_TIME_FUNCS__H__INCLUDED_)
diff --git a/protocols/MRA/Sdk/zconf.h b/protocols/MRA/Sdk/zconf.h
new file mode 100644
index 0000000000..02ce56c431
--- /dev/null
+++ b/protocols/MRA/Sdk/zconf.h
@@ -0,0 +1,428 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 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.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# define uncompress z_uncompress
+# define zError z_zError
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# define gzFile z_gzFile
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#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 <windows.h>
+ /* 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
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+# include <sys/types.h> /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+#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(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define z_off64_t off64_t
+#else
+# define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+#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/protocols/MRA/Sdk/zlib.h b/protocols/MRA/Sdk/zlib.h
new file mode 100644
index 0000000000..62d0e4675b
--- /dev/null
+++ b/protocols/MRA/Sdk/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 */