commit c068e62c8570f0a9b9539288e7b6bdb13b6e8046 Author: Gerardo Date: Mon Apr 6 13:01:34 2020 +0200 Compilacion inicial en 2017 partiendo de la version v2018 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..492be12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/Debug/* +/LicServer.ncb +/LicServer/Debug/* +/LicServer/Release/* +/LicServer/x64/Debug/* +/LicServer/x64/Release/* +/LicServer.suo +/x64/* +/LicServer/x64/Debug/* +/LicServer/x64/Debug/* +/LicServer/x64/Release/* +/x64/Debug/* diff --git a/.vs/LicServer/v15/.suo b/.vs/LicServer/v15/.suo new file mode 100644 index 0000000..12688d9 Binary files /dev/null and b/.vs/LicServer/v15/.suo differ diff --git a/.vs/LicServer/v15/Solution.VC.db b/.vs/LicServer/v15/Solution.VC.db new file mode 100644 index 0000000..e57f930 Binary files /dev/null and b/.vs/LicServer/v15/Solution.VC.db differ diff --git a/Backup/LicServer.sln b/Backup/LicServer.sln new file mode 100644 index 0000000..b6ee6ce --- /dev/null +++ b/Backup/LicServer.sln @@ -0,0 +1,89 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LicServer", "LicServer\LicServer.vcproj", "{D22EED4D-CE8E-4310-9C3A-DC7DE0368623}" + ProjectSection(ProjectDependencies) = postProject + {04E5B10E-5A75-48A2-857B-805659C7877D} = {04E5B10E-5A75-48A2-857B-805659C7877D} + {AA58C828-7025-4A4C-868E-76B8902AF6BB} = {AA58C828-7025-4A4C-868E-76B8902AF6BB} + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70} = {149E3D49-90F8-44E6-A4F9-BDEE84F65A70} + {22EEEE5A-0A71-4655-B57F-5FB8E1692389} = {22EEEE5A-0A71-4655-B57F-5FB8E1692389} + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0} = {30C05365-2DFC-4AD4-905E-8A414AE0D0A0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "licUtiles", "..\licUtiles\licUtiles.vcproj", "{04E5B10E-5A75-48A2-857B-805659C7877D}" + ProjectSection(ProjectDependencies) = postProject + {AA58C828-7025-4A4C-868E-76B8902AF6BB} = {AA58C828-7025-4A4C-868E-76B8902AF6BB} + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0} = {30C05365-2DFC-4AD4-905E-8A414AE0D0A0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utiles", "..\Utiles\utiles.vcproj", "{AA58C828-7025-4A4C-868E-76B8902AF6BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ClientLic", "..\ClientLic\ClientLic.vcproj", "{22EEEE5A-0A71-4655-B57F-5FB8E1692389}" + ProjectSection(ProjectDependencies) = postProject + {04E5B10E-5A75-48A2-857B-805659C7877D} = {04E5B10E-5A75-48A2-857B-805659C7877D} + {AA58C828-7025-4A4C-868E-76B8902AF6BB} = {AA58C828-7025-4A4C-868E-76B8902AF6BB} + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0} = {30C05365-2DFC-4AD4-905E-8A414AE0D0A0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileTransfer", "..\TransferSrv\FileTransfer\FileTransfer.vcproj", "{149E3D49-90F8-44E6-A4F9-BDEE84F65A70}" + ProjectSection(ProjectDependencies) = postProject + {AA58C828-7025-4A4C-868E-76B8902AF6BB} = {AA58C828-7025-4A4C-868E-76B8902AF6BB} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TransferSrv", "..\TransferSrv\TransferSrv\TransferSrv.vcproj", "{30C05365-2DFC-4AD4-905E-8A414AE0D0A0}" + ProjectSection(ProjectDependencies) = postProject + {AA58C828-7025-4A4C-868E-76B8902AF6BB} = {AA58C828-7025-4A4C-868E-76B8902AF6BB} + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70} = {149E3D49-90F8-44E6-A4F9-BDEE84F65A70} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|Win32.ActiveCfg = Debug|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|Win32.Build.0 = Debug|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|x64.ActiveCfg = Debug|x64 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|Win32.ActiveCfg = Release|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|Win32.Build.0 = Release|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|x64.ActiveCfg = Release|x64 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|Win32.ActiveCfg = Debug|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|Win32.Build.0 = Debug|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|x64.ActiveCfg = Debug|x64 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|Win32.ActiveCfg = Release|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|Win32.Build.0 = Release|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|x64.ActiveCfg = Release|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|Win32.Build.0 = Debug|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|x64.ActiveCfg = Debug|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|x64.Build.0 = Debug|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|Win32.ActiveCfg = Release|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|Win32.Build.0 = Release|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|x64.ActiveCfg = Release|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|x64.Build.0 = Release|x64 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|Win32.ActiveCfg = Debug|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|Win32.Build.0 = Debug|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|x64.ActiveCfg = Debug|x64 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|Win32.ActiveCfg = Release|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|Win32.Build.0 = Release|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|x64.ActiveCfg = Release|x64 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|Win32.ActiveCfg = Debug|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|Win32.Build.0 = Debug|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|x64.ActiveCfg = Debug|x64 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|Win32.ActiveCfg = Release|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|Win32.Build.0 = Release|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|x64.ActiveCfg = Release|x64 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|Win32.ActiveCfg = Debug|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|Win32.Build.0 = Debug|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|x64.ActiveCfg = Debug|x64 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|Win32.ActiveCfg = Release|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|Win32.Build.0 = Release|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/LicServer.sln b/LicServer.sln new file mode 100644 index 0000000..db7e7ea --- /dev/null +++ b/LicServer.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.329 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LicServer", "LicServer\LicServer.vcxproj", "{D22EED4D-CE8E-4310-9C3A-DC7DE0368623}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "licUtiles", "..\licUtiles\licUtiles.vcxproj", "{04E5B10E-5A75-48A2-857B-805659C7877D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utiles", "..\Utiles\utiles.vcxproj", "{AA58C828-7025-4A4C-868E-76B8902AF6BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ClientLic", "..\ClientLic\ClientLic.vcxproj", "{22EEEE5A-0A71-4655-B57F-5FB8E1692389}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileTransfer", "..\TransferSrv\FileTransfer\FileTransfer.vcxproj", "{149E3D49-90F8-44E6-A4F9-BDEE84F65A70}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TransferSrv", "..\TransferSrv\TransferSrv\TransferSrv.vcxproj", "{30C05365-2DFC-4AD4-905E-8A414AE0D0A0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|Win32.ActiveCfg = Debug|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|Win32.Build.0 = Debug|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|x64.ActiveCfg = Debug|x64 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Debug|x64.Build.0 = Debug|x64 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|Win32.ActiveCfg = Release|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|Win32.Build.0 = Release|Win32 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|x64.ActiveCfg = Release|x64 + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623}.Release|x64.Build.0 = Release|x64 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|Win32.ActiveCfg = Debug|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|Win32.Build.0 = Debug|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|x64.ActiveCfg = Debug|x64 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Debug|x64.Build.0 = Debug|x64 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|Win32.ActiveCfg = Release|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|Win32.Build.0 = Release|Win32 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|x64.ActiveCfg = Release|x64 + {04E5B10E-5A75-48A2-857B-805659C7877D}.Release|x64.Build.0 = Release|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|Win32.Build.0 = Debug|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|x64.ActiveCfg = Debug|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Debug|x64.Build.0 = Debug|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|Win32.ActiveCfg = Release|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|Win32.Build.0 = Release|Win32 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|x64.ActiveCfg = Release|x64 + {AA58C828-7025-4A4C-868E-76B8902AF6BB}.Release|x64.Build.0 = Release|x64 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|Win32.ActiveCfg = Debug|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|Win32.Build.0 = Debug|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|x64.ActiveCfg = Debug|x64 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Debug|x64.Build.0 = Debug|x64 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|Win32.ActiveCfg = Release|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|Win32.Build.0 = Release|Win32 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|x64.ActiveCfg = Release|x64 + {22EEEE5A-0A71-4655-B57F-5FB8E1692389}.Release|x64.Build.0 = Release|x64 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|Win32.ActiveCfg = Debug|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|Win32.Build.0 = Debug|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|x64.ActiveCfg = Debug|x64 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Debug|x64.Build.0 = Debug|x64 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|Win32.ActiveCfg = Release|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|Win32.Build.0 = Release|Win32 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|x64.ActiveCfg = Release|x64 + {149E3D49-90F8-44E6-A4F9-BDEE84F65A70}.Release|x64.Build.0 = Release|x64 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|Win32.ActiveCfg = Debug|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|Win32.Build.0 = Debug|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|x64.ActiveCfg = Debug|x64 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Debug|x64.Build.0 = Debug|x64 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|Win32.ActiveCfg = Release|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|Win32.Build.0 = Release|Win32 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|x64.ActiveCfg = Release|x64 + {30C05365-2DFC-4AD4-905E-8A414AE0D0A0}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CA61B304-F115-4AA3-A278-4C5ED9879F04} + EndGlobalSection +EndGlobal diff --git a/LicServer/AppClasSrv.cpp b/LicServer/AppClasSrv.cpp new file mode 100644 index 0000000..3a1a0d0 --- /dev/null +++ b/LicServer/AppClasSrv.cpp @@ -0,0 +1,54 @@ +#include "StdAfx.h" +#include "AppClasSrv.h" +#include "_app.h" + +AppClasSrv::AppClasSrv(void) +{ + key[0]=0; + user[0]=0; + path[0]=0; + + C_app::GetApp()->log.l_lisener=this; + strcpy(C_app::GetApp()->log.nombre,"LicServer"); +} + +AppClasSrv::~AppClasSrv(void) +{ +} + +void AppClasSrv::log_ext( __time64_t tiemp, char *modulo, char *fmt ) +{ + char tiem[32]; + char str[1024]; + strftime(tiem, 20, "%Y-%m-%d %H:%M:%S", localtime(&tiemp)); + sprintf_s(str,1024, "%s %-12s %s\r\n", + (char *) LPCTSTR (tiem), + (char *) LPCTSTR (modulo), + (char *) LPCTSTR (fmt)); + _tprintf(str); +} +//************************************************************************************ +void AppClasSrv::runApp() +{ + while(true) + Sleep(1000); +} +//************************************************************************************ +bool AppClasSrv::getClave( char* clave, char* producto ) +{ + strcpy(clave, key); + + return true; +} +//************************************************************************************ +void AppClasSrv::muestaError( char* info, char* producto ) +{ + C_log::log("Mens_lic", info); +} +//************************************************************************************ +bool AppClasSrv::descargaInstalador( Licencia *lic ) +{ + return true; +} + +//************************************************************************************ \ No newline at end of file diff --git a/LicServer/AppClasSrv.h b/LicServer/AppClasSrv.h new file mode 100644 index 0000000..551efb0 --- /dev/null +++ b/LicServer/AppClasSrv.h @@ -0,0 +1,23 @@ +#pragma once +#include "_log.h" + +class AppClasSrv: public C_escucha_log, public LicClientEscucha +{ +public: + AppClasSrv(void); + ~AppClasSrv(void); + + char key[32]; + char user[32]; + char path[256]; + + virtual void log_ext( __time64_t tiemp, char *modulo, char *fmt ); + void runApp(); + + virtual bool getClave(char* clave, char* producto ); + + virtual void muestaError( char* info, char* producto ); + + virtual bool descargaInstalador( Licencia *lic ); + +}; diff --git a/LicServer/CppSQLite3.cpp b/LicServer/CppSQLite3.cpp new file mode 100644 index 0000000..46933cc --- /dev/null +++ b/LicServer/CppSQLite3.cpp @@ -0,0 +1,1591 @@ +//////////////////////////////////////////////////////////////////////////////// +// CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library. +// +// Copyright (c) 2004..2007 Rob Groves. All Rights Reserved. rob.groves@btinternet.com +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose, without fee, and without a written +// agreement, is hereby granted, provided that the above copyright notice, +// this paragraph and the following two paragraphs appear in all copies, +// modifications, and distributions. +// +// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, +// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST +// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF +// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION +// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +// +// V3.0 03/08/2004 -Initial Version for sqlite3 +// +// V3.1 16/09/2004 -Implemented getXXXXField using sqlite3 functions +// -Added CppSQLiteDB3::tableExists() +// +// V3.2 01/07/2005 -Fixed execScalar to handle a NULL result +// 12/07/2007 -Added int64 functions to CppSQLite3Query +// -Throw exception from CppSQLite3DB::close() if error +// -Trap above exception in CppSQLite3DB::~CppSQLite3DB() +// -Fix to CppSQLite3DB::compile() as provided by Dave Rollins. +// -sqlite3_prepare replaced with sqlite3_prepare_v2 +// -Added Name based parameter binding to CppSQLite3Statement. +//////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "CppSQLite3.h" +#include + #include +#include +#pragma warning( disable : 4996 ) + +// Named constant for passing to CppSQLite3Exception when passing it a string +// that cannot be deleted. +static const bool DONT_DELETE_MSG=false; + +//////////////////////////////////////////////////////////////////////////////// +// Prototypes for SQLite functions not included in SQLite DLL, but copied below +// from SQLite encode.c +//////////////////////////////////////////////////////////////////////////////// +int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out); +int sqlite3_decode_binary(const unsigned char *in, unsigned char *out); + +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3Exception::CppSQLite3Exception(const int nErrCode, + char* szErrMess, + bool bDeleteMsg/*=true*/) : + mnErrCode(nErrCode) +{ + mpszErrMess = sqlite3_mprintf("%s[%d]: %s", + errorCodeAsString(nErrCode), + nErrCode, + szErrMess ? szErrMess : ""); + + if (bDeleteMsg && szErrMess) + { + sqlite3_free(szErrMess); + } +} + + +CppSQLite3Exception::CppSQLite3Exception(const CppSQLite3Exception& e) : + mnErrCode(e.mnErrCode) +{ + mpszErrMess = 0; + if (e.mpszErrMess) + { + mpszErrMess = sqlite3_mprintf("%s", e.mpszErrMess); + } +} + + +const char* CppSQLite3Exception::errorCodeAsString(int nErrCode) +{ + switch (nErrCode) + { + case SQLITE_OK : return "SQLITE_OK"; + case SQLITE_ERROR : return "SQLITE_ERROR"; + case SQLITE_INTERNAL : return "SQLITE_INTERNAL"; + case SQLITE_PERM : return "SQLITE_PERM"; + case SQLITE_ABORT : return "SQLITE_ABORT"; + case SQLITE_BUSY : return "SQLITE_BUSY"; + case SQLITE_LOCKED : return "SQLITE_LOCKED"; + case SQLITE_NOMEM : return "SQLITE_NOMEM"; + case SQLITE_READONLY : return "SQLITE_READONLY"; + case SQLITE_INTERRUPT : return "SQLITE_INTERRUPT"; + case SQLITE_IOERR : return "SQLITE_IOERR"; + case SQLITE_CORRUPT : return "SQLITE_CORRUPT"; + case SQLITE_NOTFOUND : return "SQLITE_NOTFOUND"; + case SQLITE_FULL : return "SQLITE_FULL"; + case SQLITE_CANTOPEN : return "SQLITE_CANTOPEN"; + case SQLITE_PROTOCOL : return "SQLITE_PROTOCOL"; + case SQLITE_EMPTY : return "SQLITE_EMPTY"; + case SQLITE_SCHEMA : return "SQLITE_SCHEMA"; + case SQLITE_TOOBIG : return "SQLITE_TOOBIG"; + case SQLITE_CONSTRAINT : return "SQLITE_CONSTRAINT"; + case SQLITE_MISMATCH : return "SQLITE_MISMATCH"; + case SQLITE_MISUSE : return "SQLITE_MISUSE"; + case SQLITE_NOLFS : return "SQLITE_NOLFS"; + case SQLITE_AUTH : return "SQLITE_AUTH"; + case SQLITE_FORMAT : return "SQLITE_FORMAT"; + case SQLITE_RANGE : return "SQLITE_RANGE"; + case SQLITE_ROW : return "SQLITE_ROW"; + case SQLITE_DONE : return "SQLITE_DONE"; + case CPPSQLITE_ERROR : return "CPPSQLITE_ERROR"; + default: return "UNKNOWN_ERROR"; + } +} + + +CppSQLite3Exception::~CppSQLite3Exception() +{ + if (mpszErrMess) + { + sqlite3_free(mpszErrMess); + mpszErrMess = 0; + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3Buffer::CppSQLite3Buffer() +{ + mpBuf = 0; +} + + +CppSQLite3Buffer::~CppSQLite3Buffer() +{ + clear(); +} + + +void CppSQLite3Buffer::clear() +{ + if (mpBuf) + { + sqlite3_free(mpBuf); + mpBuf = 0; + } + +} + + +const char* CppSQLite3Buffer::format(const char* szFormat, ...) +{ + clear(); + va_list va; + va_start(va, szFormat); + mpBuf = sqlite3_vmprintf(szFormat, va); + va_end(va); + return mpBuf; +} + + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3Binary::CppSQLite3Binary() : + mpBuf(0), + mnBinaryLen(0), + mnBufferLen(0), + mnEncodedLen(0), + mbEncoded(false) +{ +} + + +CppSQLite3Binary::~CppSQLite3Binary() +{ + clear(); +} + + +void CppSQLite3Binary::setBinary(const unsigned char* pBuf, int nLen) +{ + mpBuf = allocBuffer(nLen); + memcpy(mpBuf, pBuf, nLen); +} + + +void CppSQLite3Binary::setEncoded(const unsigned char* pBuf) +{ + clear(); + + mnEncodedLen = strlen((const char*)pBuf); + mnBufferLen = mnEncodedLen + 1; // Allow for NULL terminator + + mpBuf = (unsigned char*)malloc(mnBufferLen); + + if (!mpBuf) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Cannot allocate memory", + DONT_DELETE_MSG); + } + + memcpy(mpBuf, pBuf, mnBufferLen); + mbEncoded = true; +} + + +const unsigned char* CppSQLite3Binary::getEncoded() +{ + if (!mbEncoded) + { + unsigned char* ptmp = (unsigned char*)malloc(mnBinaryLen); + memcpy(ptmp, mpBuf, mnBinaryLen); + mnEncodedLen = sqlite3_encode_binary(ptmp, mnBinaryLen, mpBuf); + free(ptmp); + mbEncoded = true; + } + + return mpBuf; +} + + +const unsigned char* CppSQLite3Binary::getBinary() +{ + if (mbEncoded) + { + // in/out buffers can be the same + mnBinaryLen = sqlite3_decode_binary(mpBuf, mpBuf); + + if (mnBinaryLen == -1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Cannot decode binary", + DONT_DELETE_MSG); + } + + mbEncoded = false; + } + + return mpBuf; +} + + +int CppSQLite3Binary::getBinaryLength() +{ + getBinary(); + return mnBinaryLen; +} + + +unsigned char* CppSQLite3Binary::allocBuffer(int nLen) +{ + clear(); + + // Allow extra space for encoded binary as per comments in + // SQLite encode.c See bottom of this file for implementation + // of SQLite functions use 3 instead of 2 just to be sure ;-) + mnBinaryLen = nLen; + mnBufferLen = 3 + (257*nLen)/254; + + mpBuf = (unsigned char*)malloc(mnBufferLen); + + if (!mpBuf) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Cannot allocate memory", + DONT_DELETE_MSG); + } + + mbEncoded = false; + + return mpBuf; +} + + +void CppSQLite3Binary::clear() +{ + if (mpBuf) + { + mnBinaryLen = 0; + mnBufferLen = 0; + free(mpBuf); + mpBuf = 0; + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3Query::CppSQLite3Query() +{ + mpVM = 0; + mbEof = true; + mnCols = 0; + mbOwnVM = false; +} + + +CppSQLite3Query::CppSQLite3Query(const CppSQLite3Query& rQuery) +{ + mpVM = rQuery.mpVM; + // Only one object can own the VM + const_cast(rQuery).mpVM = 0; + mbEof = rQuery.mbEof; + mnCols = rQuery.mnCols; + mbOwnVM = rQuery.mbOwnVM; +} + + +CppSQLite3Query::CppSQLite3Query(sqlite3* pDB, + sqlite3_stmt* pVM, + bool bEof, + bool bOwnVM/*=true*/) +{ + mpDB = pDB; + mpVM = pVM; + mbEof = bEof; + mnCols = sqlite3_column_count(mpVM); + mbOwnVM = bOwnVM; +} + + +CppSQLite3Query::~CppSQLite3Query() +{ + try + { + finalize(); + } + catch (...) + { + } +} + + +CppSQLite3Query& CppSQLite3Query::operator=(const CppSQLite3Query& rQuery) +{ + try + { + finalize(); + } + catch (...) + { + } + mpVM = rQuery.mpVM; + // Only one object can own the VM + const_cast(rQuery).mpVM = 0; + mbEof = rQuery.mbEof; + mnCols = rQuery.mnCols; + mbOwnVM = rQuery.mbOwnVM; + return *this; +} + + +int CppSQLite3Query::numFields() +{ + checkVM(); + return mnCols; +} + + +const char* CppSQLite3Query::fieldValue(int nField) +{ + checkVM(); + + if (nField < 0 || nField > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + return (const char*)sqlite3_column_text(mpVM, nField); +} + + +const char* CppSQLite3Query::fieldValue(const char* szField) +{ + int nField = fieldIndex(szField); + return (const char*)sqlite3_column_text(mpVM, nField); +} + + +int CppSQLite3Query::getIntField(int nField, int nNullValue/*=0*/) +{ + if (fieldDataType(nField) == SQLITE_NULL) + { + return nNullValue; + } + else + { + return sqlite3_column_int(mpVM, nField); + } +} + + +int CppSQLite3Query::getIntField(const char* szField, int nNullValue/*=0*/) +{ + int nField = fieldIndex(szField); + return getIntField(nField, nNullValue); +} + + +sqlite_int64 CppSQLite3Query::getInt64Field(int nField, sqlite_int64 nNullValue/*=0*/) +{ + if (fieldDataType(nField) == SQLITE_NULL) + { + return nNullValue; + } + else + { + return sqlite3_column_int64(mpVM, nField); + } +} + + +sqlite_int64 CppSQLite3Query::getInt64Field(const char* szField, sqlite_int64 nNullValue/*=0*/) +{ + int nField = fieldIndex(szField); + return getInt64Field(nField, nNullValue); +} + + +double CppSQLite3Query::getFloatField(int nField, double fNullValue/*=0.0*/) +{ + if (fieldDataType(nField) == SQLITE_NULL) + { + return fNullValue; + } + else + { + return sqlite3_column_double(mpVM, nField); + } +} + + +double CppSQLite3Query::getFloatField(const char* szField, double fNullValue/*=0.0*/) +{ + int nField = fieldIndex(szField); + return getFloatField(nField, fNullValue); +} + + +const char* CppSQLite3Query::getStringField(int nField, const char* szNullValue/*=""*/) +{ + if (fieldDataType(nField) == SQLITE_NULL) + { + return szNullValue; + } + else + { + return (const char*)sqlite3_column_text(mpVM, nField); + } +} + + +const char* CppSQLite3Query::getStringField(const char* szField, const char* szNullValue/*=""*/) +{ + int nField = fieldIndex(szField); + return getStringField(nField, szNullValue); +} + + +const unsigned char* CppSQLite3Query::getBlobField(int nField, int& nLen) +{ + checkVM(); + + if (nField < 0 || nField > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + nLen = sqlite3_column_bytes(mpVM, nField); + return (const unsigned char*)sqlite3_column_blob(mpVM, nField); +} + + +const unsigned char* CppSQLite3Query::getBlobField(const char* szField, int& nLen) +{ + int nField = fieldIndex(szField); + return getBlobField(nField, nLen); +} + + +bool CppSQLite3Query::fieldIsNull(int nField) +{ + return (fieldDataType(nField) == SQLITE_NULL); +} + + +bool CppSQLite3Query::fieldIsNull(const char* szField) +{ + int nField = fieldIndex(szField); + return (fieldDataType(nField) == SQLITE_NULL); +} + + +int CppSQLite3Query::fieldIndex(const char* szField) +{ + checkVM(); + + if (szField) + { + for (int nField = 0; nField < mnCols; nField++) + { + const char* szTemp = sqlite3_column_name(mpVM, nField); + + if (strcmp(szField, szTemp) == 0) + { + return nField; + } + } + } + + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field name requested", + DONT_DELETE_MSG); +} + + +const char* CppSQLite3Query::fieldName(int nCol) +{ + checkVM(); + + if (nCol < 0 || nCol > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + return sqlite3_column_name(mpVM, nCol); +} + + +const char* CppSQLite3Query::fieldDeclType(int nCol) +{ + checkVM(); + + if (nCol < 0 || nCol > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + return sqlite3_column_decltype(mpVM, nCol); +} + + +int CppSQLite3Query::fieldDataType(int nCol) +{ + checkVM(); + + if (nCol < 0 || nCol > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + return sqlite3_column_type(mpVM, nCol); +} + + +bool CppSQLite3Query::eof() +{ + checkVM(); + return mbEof; +} + + +void CppSQLite3Query::nextRow() +{ + checkVM(); + + int nRet = sqlite3_step(mpVM); + + if (nRet == SQLITE_DONE) + { + // no rows + mbEof = true; + } + else if (nRet == SQLITE_ROW) + { + // more rows, nothing to do + } + else + { + nRet = sqlite3_finalize(mpVM); + mpVM = 0; + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, + (char*)szError, + DONT_DELETE_MSG); + } +} + + +void CppSQLite3Query::finalize() +{ + if (mpVM && mbOwnVM) + { + int nRet = sqlite3_finalize(mpVM); + mpVM = 0; + if (nRet != SQLITE_OK) + { + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } + } +} + + +void CppSQLite3Query::checkVM() +{ + if (mpVM == 0) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Null Virtual Machine pointer", + DONT_DELETE_MSG); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3Table::CppSQLite3Table() +{ + mpaszResults = 0; + mnRows = 0; + mnCols = 0; + mnCurrentRow = 0; +} + + +CppSQLite3Table::CppSQLite3Table(const CppSQLite3Table& rTable) +{ + mpaszResults = rTable.mpaszResults; + // Only one object can own the results + const_cast(rTable).mpaszResults = 0; + mnRows = rTable.mnRows; + mnCols = rTable.mnCols; + mnCurrentRow = rTable.mnCurrentRow; +} + + +CppSQLite3Table::CppSQLite3Table(char** paszResults, int nRows, int nCols) +{ + mpaszResults = paszResults; + mnRows = nRows; + mnCols = nCols; + mnCurrentRow = 0; +} + + +CppSQLite3Table::~CppSQLite3Table() +{ + try + { + finalize(); + } + catch (...) + { + } +} + + +CppSQLite3Table& CppSQLite3Table::operator=(const CppSQLite3Table& rTable) +{ + try + { + finalize(); + } + catch (...) + { + } + mpaszResults = rTable.mpaszResults; + // Only one object can own the results + const_cast(rTable).mpaszResults = 0; + mnRows = rTable.mnRows; + mnCols = rTable.mnCols; + mnCurrentRow = rTable.mnCurrentRow; + return *this; +} + + +void CppSQLite3Table::finalize() +{ + if (mpaszResults) + { + sqlite3_free_table(mpaszResults); + mpaszResults = 0; + } +} + + +int CppSQLite3Table::numFields() +{ + checkResults(); + return mnCols; +} + + +int CppSQLite3Table::numRows() +{ + checkResults(); + return mnRows; +} + + +const char* CppSQLite3Table::fieldValue(int nField) +{ + checkResults(); + + if (nField < 0 || nField > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + int nIndex = (mnCurrentRow*mnCols) + mnCols + nField; + return mpaszResults[nIndex]; +} + + +const char* CppSQLite3Table::fieldValue(const char* szField) +{ + checkResults(); + + if (szField) + { + for (int nField = 0; nField < mnCols; nField++) + { + if (strcmp(szField, mpaszResults[nField]) == 0) + { + int nIndex = (mnCurrentRow*mnCols) + mnCols + nField; + return mpaszResults[nIndex]; + } + } + } + + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field name requested", + DONT_DELETE_MSG); +} + + +int CppSQLite3Table::getIntField(int nField, int nNullValue/*=0*/) +{ + if (fieldIsNull(nField)) + { + return nNullValue; + } + else + { + return atoi(fieldValue(nField)); + } +} + + +int CppSQLite3Table::getIntField(const char* szField, int nNullValue/*=0*/) +{ + if (fieldIsNull(szField)) + { + return nNullValue; + } + else + { + return atoi(fieldValue(szField)); + } +} + + +double CppSQLite3Table::getFloatField(int nField, double fNullValue/*=0.0*/) +{ + if (fieldIsNull(nField)) + { + return fNullValue; + } + else + { + return atof(fieldValue(nField)); + } +} + + +double CppSQLite3Table::getFloatField(const char* szField, double fNullValue/*=0.0*/) +{ + if (fieldIsNull(szField)) + { + return fNullValue; + } + else + { + return atof(fieldValue(szField)); + } +} + + +const char* CppSQLite3Table::getStringField(int nField, const char* szNullValue/*=""*/) +{ + if (fieldIsNull(nField)) + { + return szNullValue; + } + else + { + return fieldValue(nField); + } +} + + +const char* CppSQLite3Table::getStringField(const char* szField, const char* szNullValue/*=""*/) +{ + if (fieldIsNull(szField)) + { + return szNullValue; + } + else + { + return fieldValue(szField); + } +} + + +bool CppSQLite3Table::fieldIsNull(int nField) +{ + checkResults(); + return (fieldValue(nField) == 0); +} + + +bool CppSQLite3Table::fieldIsNull(const char* szField) +{ + checkResults(); + return (fieldValue(szField) == 0); +} + + +const char* CppSQLite3Table::fieldName(int nCol) +{ + checkResults(); + + if (nCol < 0 || nCol > mnCols-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid field index requested", + DONT_DELETE_MSG); + } + + return mpaszResults[nCol]; +} + + +void CppSQLite3Table::setRow(int nRow) +{ + checkResults(); + + if (nRow < 0 || nRow > mnRows-1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid row index requested", + DONT_DELETE_MSG); + } + + mnCurrentRow = nRow; +} + + +void CppSQLite3Table::checkResults() +{ + if (mpaszResults == 0) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Null Results pointer", + DONT_DELETE_MSG); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3Statement::CppSQLite3Statement() +{ + mpDB = 0; + mpVM = 0; +} + + +CppSQLite3Statement::CppSQLite3Statement(const CppSQLite3Statement& rStatement) +{ + mpDB = rStatement.mpDB; + mpVM = rStatement.mpVM; + // Only one object can own VM + const_cast(rStatement).mpVM = 0; +} + + +CppSQLite3Statement::CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM) +{ + mpDB = pDB; + mpVM = pVM; +} + + +CppSQLite3Statement::~CppSQLite3Statement() +{ + try + { + finalize(); + } + catch (...) + { + } +} + + +CppSQLite3Statement& CppSQLite3Statement::operator=(const CppSQLite3Statement& rStatement) +{ + mpDB = rStatement.mpDB; + mpVM = rStatement.mpVM; + // Only one object can own VM + const_cast(rStatement).mpVM = 0; + return *this; +} + + +int CppSQLite3Statement::execDML() +{ + checkDB(); + checkVM(); + + const char* szError=0; + + int nRet = sqlite3_step(mpVM); + + if (nRet == SQLITE_DONE) + { + int nRowsChanged = sqlite3_changes(mpDB); + + nRet = sqlite3_reset(mpVM); + + if (nRet != SQLITE_OK) + { + szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } + + return nRowsChanged; + } + else + { + nRet = sqlite3_reset(mpVM); + szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } +} + + +CppSQLite3Query CppSQLite3Statement::execQuery() +{ + checkDB(); + checkVM(); + + int nRet = sqlite3_step(mpVM); + + if (nRet == SQLITE_DONE) + { + // no rows + return CppSQLite3Query(mpDB, mpVM, true/*eof*/, false); + } + else if (nRet == SQLITE_ROW) + { + // at least 1 row + return CppSQLite3Query(mpDB, mpVM, false/*eof*/, false); + } + else + { + nRet = sqlite3_reset(mpVM); + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } +} + + +void CppSQLite3Statement::bind(int nParam, const char* szValue) +{ + checkVM(); + int nRes = sqlite3_bind_text(mpVM, nParam, szValue, -1, SQLITE_TRANSIENT); + + if (nRes != SQLITE_OK) + { + throw CppSQLite3Exception(nRes, + "Error binding string param", + DONT_DELETE_MSG); + } +} + + +void CppSQLite3Statement::bind(int nParam, const int nValue) +{ + checkVM(); + int nRes = sqlite3_bind_int(mpVM, nParam, nValue); + + if (nRes != SQLITE_OK) + { + throw CppSQLite3Exception(nRes, + "Error binding int param", + DONT_DELETE_MSG); + } +} + + +void CppSQLite3Statement::bind(int nParam, const double dValue) +{ + checkVM(); + int nRes = sqlite3_bind_double(mpVM, nParam, dValue); + + if (nRes != SQLITE_OK) + { + throw CppSQLite3Exception(nRes, + "Error binding double param", + DONT_DELETE_MSG); + } +} + + +void CppSQLite3Statement::bind(int nParam, const unsigned char* blobValue, int nLen) +{ + checkVM(); + int nRes = sqlite3_bind_blob(mpVM, nParam, + (const void*)blobValue, nLen, SQLITE_TRANSIENT); + + if (nRes != SQLITE_OK) + { + throw CppSQLite3Exception(nRes, + "Error binding blob param", + DONT_DELETE_MSG); + } +} + + +void CppSQLite3Statement::bindNull(int nParam) +{ + checkVM(); + int nRes = sqlite3_bind_null(mpVM, nParam); + + if (nRes != SQLITE_OK) + { + throw CppSQLite3Exception(nRes, + "Error binding NULL param", + DONT_DELETE_MSG); + } +} + + + +int CppSQLite3Statement::bindParameterIndex(const char* szParam) +{ + checkVM(); + + int nParam = sqlite3_bind_parameter_index(mpVM, szParam); + +int nn = sqlite3_bind_parameter_count(mpVM); +const char* sz1 = sqlite3_bind_parameter_name(mpVM, 1); +const char* sz2 = sqlite3_bind_parameter_name(mpVM, 2); + + if (!nParam) + { + char buf[128]; + sprintf(buf, "Parameter '%s' is not valid for this statement", szParam); + throw CppSQLite3Exception(CPPSQLITE_ERROR, buf, DONT_DELETE_MSG); + } + + return nParam; +} + + +void CppSQLite3Statement::bind(const char* szParam, const char* szValue) +{ + int nParam = bindParameterIndex(szParam); + bind(nParam, szValue); +} + + +void CppSQLite3Statement::bind(const char* szParam, const int nValue) +{ + int nParam = bindParameterIndex(szParam); + bind(nParam, nValue); +} + +void CppSQLite3Statement::bind(const char* szParam, const double dwValue) +{ + int nParam = bindParameterIndex(szParam); + bind(nParam, dwValue); +} + +void CppSQLite3Statement::bind(const char* szParam, const unsigned char* blobValue, int nLen) +{ + int nParam = bindParameterIndex(szParam); + bind(nParam, blobValue, nLen); +} + + +void CppSQLite3Statement::bindNull(const char* szParam) +{ + int nParam = bindParameterIndex(szParam); + bindNull(nParam); +} + + +void CppSQLite3Statement::reset() +{ + if (mpVM) + { + int nRet = sqlite3_reset(mpVM); + + if (nRet != SQLITE_OK) + { + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } + } +} + + +void CppSQLite3Statement::finalize() +{ + if (mpVM) + { + int nRet = sqlite3_finalize(mpVM); + mpVM = 0; + + if (nRet != SQLITE_OK) + { + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } + } +} + + +void CppSQLite3Statement::checkDB() +{ + if (mpDB == 0) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Database not open", + DONT_DELETE_MSG); + } +} + + +void CppSQLite3Statement::checkVM() +{ + if (mpVM == 0) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Null Virtual Machine pointer", + DONT_DELETE_MSG); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +CppSQLite3DB::CppSQLite3DB() +{ + mpDB = 0; + mnBusyTimeoutMs = 60000; // 60 seconds +} + + +CppSQLite3DB::CppSQLite3DB(const CppSQLite3DB& db) +{ + mpDB = db.mpDB; + mnBusyTimeoutMs = 60000; // 60 seconds +} + + +CppSQLite3DB::~CppSQLite3DB() +{ + try + { + close(); + } + catch (...) + { + } +} + + +CppSQLite3DB& CppSQLite3DB::operator=(const CppSQLite3DB& db) +{ + mpDB = db.mpDB; + mnBusyTimeoutMs = 60000; // 60 seconds + return *this; +} + + +void CppSQLite3DB::open(const char* szFile) +{ + int nRet = sqlite3_open(szFile, &mpDB); + + if (nRet != SQLITE_OK) + { + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } + + setBusyTimeout(mnBusyTimeoutMs); +} + + +void CppSQLite3DB::close() +{ + if (mpDB) + { + if (sqlite3_close(mpDB) == SQLITE_OK) + { + mpDB = 0; + } + else + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Unable to close database", + DONT_DELETE_MSG); + } + } +} + + +CppSQLite3Statement CppSQLite3DB::compileStatement(const char* szSQL) +{ + checkDB(); + + sqlite3_stmt* pVM = compile(szSQL); + return CppSQLite3Statement(mpDB, pVM); +} + + +bool CppSQLite3DB::tableExists(const char* szTable) +{ + char szSQL[256]; + sprintf(szSQL, + "select count(*) from sqlite_master where type='table' and name='%s'", + szTable); + int nRet = execScalar(szSQL); + return (nRet > 0); +} + + +int CppSQLite3DB::execDML(const char* szSQL) +{ + checkDB(); + + char* szError=0; + + int nRet = sqlite3_exec(mpDB, szSQL, 0, 0, &szError); + + if (nRet == SQLITE_OK) + { + return sqlite3_changes(mpDB); + } + else + { + throw CppSQLite3Exception(nRet, szError); + } +} + + +CppSQLite3Query CppSQLite3DB::execQuery(const char* szSQL) +{ + checkDB(); + + sqlite3_stmt* pVM = compile(szSQL); + + int nRet = sqlite3_step(pVM); + + if (nRet == SQLITE_DONE) + { + // no rows + return CppSQLite3Query(mpDB, pVM, true/*eof*/); + } + else if (nRet == SQLITE_ROW) + { + // at least 1 row + return CppSQLite3Query(mpDB, pVM, false/*eof*/); + } + else + { + nRet = sqlite3_finalize(pVM); + const char* szError= sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); + } +} + + +int CppSQLite3DB::execScalar(const char* szSQL, int nNullValue/*=0*/) +{ + CppSQLite3Query q = execQuery(szSQL); + + if (q.eof() || q.numFields() < 1) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Invalid scalar query", + DONT_DELETE_MSG); + } + + return q.getIntField(0, nNullValue); +} + + +CppSQLite3Table CppSQLite3DB::getTable(const char* szSQL) +{ + checkDB(); + + char* szError=0; + char** paszResults=0; + int nRet; + int nRows(0); + int nCols(0); + + nRet = sqlite3_get_table(mpDB, szSQL, &paszResults, &nRows, &nCols, &szError); + + if (nRet == SQLITE_OK) + { + return CppSQLite3Table(paszResults, nRows, nCols); + } + else + { + throw CppSQLite3Exception(nRet, szError); + } +} + + +sqlite_int64 CppSQLite3DB::lastRowId() +{ + return sqlite3_last_insert_rowid(mpDB); +} + + +void CppSQLite3DB::setBusyTimeout(int nMillisecs) +{ + mnBusyTimeoutMs = nMillisecs; + sqlite3_busy_timeout(mpDB, mnBusyTimeoutMs); +} + + +void CppSQLite3DB::checkDB() +{ + if (!mpDB) + { + throw CppSQLite3Exception(CPPSQLITE_ERROR, + "Database not open", + DONT_DELETE_MSG); + } +} + + +sqlite3_stmt* CppSQLite3DB::compile(const char* szSQL) +{ + checkDB(); + + const char* szTail=0; + sqlite3_stmt* pVM; + + int nRet = sqlite3_prepare_v2(mpDB, szSQL, -1, &pVM, &szTail); + + if (nRet != SQLITE_OK) + { + const char* szError = sqlite3_errmsg(mpDB); + throw CppSQLite3Exception(nRet, + (char*)szError, + DONT_DELETE_MSG); + } + + return pVM; +} + +bool CppSQLite3DB::IsAutoCommitOn() +{ + checkDB(); + return sqlite3_get_autocommit(mpDB) ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// +// SQLite encode.c reproduced here, containing implementation notes and source +// for sqlite3_encode_binary() and sqlite3_decode_binary() +//////////////////////////////////////////////////////////////////////////////// + +/* +** 2002 April 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains helper routines used to translate binary data into +** a null-terminated string (suitable for use in SQLite) and back again. +** These are convenience routines for use by people who want to store binary +** data in an SQLite database. The code in this file is not used by any other +** part of the SQLite library. +** +** $Id: encode.c,v 1.10 2004/01/14 21:59:23 drh Exp $ +*/ + +/* +** How This Encoder Works +** +** The output is allowed to contain any character except 0x27 (') and +** 0x00. This is accomplished by using an escape character to encode +** 0x27 and 0x00 as a two-byte sequence. The escape character is always +** 0x01. An 0x00 is encoded as the two byte sequence 0x01 0x01. The +** 0x27 character is encoded as the two byte sequence 0x01 0x03. Finally, +** the escape character itself is encoded as the two-character sequence +** 0x01 0x02. +** +** To summarize, the encoder works by using an escape sequences as follows: +** +** 0x00 -> 0x01 0x01 +** 0x01 -> 0x01 0x02 +** 0x27 -> 0x01 0x03 +** +** If that were all the encoder did, it would work, but in certain cases +** it could double the size of the encoded string. For example, to +** encode a string of 100 0x27 characters would require 100 instances of +** the 0x01 0x03 escape sequence resulting in a 200-character output. +** We would prefer to keep the size of the encoded string smaller than +** this. +** +** To minimize the encoding size, we first add a fixed offset value to each +** byte in the sequence. The addition is modulo 256. (That is to say, if +** the sum of the original character value and the offset exceeds 256, then +** the higher order bits are truncated.) The offset is chosen to minimize +** the number of characters in the string that need to be escaped. For +** example, in the case above where the string was composed of 100 0x27 +** characters, the offset might be 0x01. Each of the 0x27 characters would +** then be converted into an 0x28 character which would not need to be +** escaped at all and so the 100 character input string would be converted +** into just 100 characters of output. Actually 101 characters of output - +** we have to record the offset used as the first byte in the sequence so +** that the string can be decoded. Since the offset value is stored as +** part of the output string and the output string is not allowed to contain +** characters 0x00 or 0x27, the offset cannot be 0x00 or 0x27. +** +** Here, then, are the encoding steps: +** +** (1) Choose an offset value and make it the first character of +** output. +** +** (2) Copy each input character into the output buffer, one by +** one, adding the offset value as you copy. +** +** (3) If the value of an input character plus offset is 0x00, replace +** that one character by the two-character sequence 0x01 0x01. +** If the sum is 0x01, replace it with 0x01 0x02. If the sum +** is 0x27, replace it with 0x01 0x03. +** +** (4) Put a 0x00 terminator at the end of the output. +** +** Decoding is obvious: +** +** (5) Copy encoded characters except the first into the decode +** buffer. Set the first encoded character aside for use as +** the offset in step 7 below. +** +** (6) Convert each 0x01 0x01 sequence into a single character 0x00. +** Convert 0x01 0x02 into 0x01. Convert 0x01 0x03 into 0x27. +** +** (7) Subtract the offset value that was the first character of +** the encoded buffer from all characters in the output buffer. +** +** The only tricky part is step (1) - how to compute an offset value to +** minimize the size of the output buffer. This is accomplished by testing +** all offset values and picking the one that results in the fewest number +** of escapes. To do that, we first scan the entire input and count the +** number of occurances of each character value in the input. Suppose +** the number of 0x00 characters is N(0), the number of occurances of 0x01 +** is N(1), and so forth up to the number of occurances of 0xff is N(255). +** An offset of 0 is not allowed so we don't have to test it. The number +** of escapes required for an offset of 1 is N(1)+N(2)+N(40). The number +** of escapes required for an offset of 2 is N(2)+N(3)+N(41). And so forth. +** In this way we find the offset that gives the minimum number of escapes, +** and thus minimizes the length of the output string. +*/ + +/* +** Encode a binary buffer "in" of size n bytes so that it contains +** no instances of characters '\'' or '\000'. The output is +** null-terminated and can be used as a string value in an INSERT +** or UPDATE statement. Use sqlite3_decode_binary() to convert the +** string back into its original binary. +** +** The result is written into a preallocated output buffer "out". +** "out" must be able to hold at least 2 +(257*n)/254 bytes. +** In other words, the output will be expanded by as much as 3 +** bytes for every 254 bytes of input plus 2 bytes of fixed overhead. +** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.) +** +** The return value is the number of characters in the encoded +** string, excluding the "\000" terminator. +*/ +int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out){ + int i, j, e, m; + int cnt[256]; + if( n<=0 ){ + out[0] = 'x'; + out[1] = 0; + return 1; + } + memset(cnt, 0, sizeof(cnt)); + for(i=n-1; i>=0; i--){ cnt[in[i]]++; } + m = n; + for(i=1; i<256; i++){ + int sum; + if( i=='\'' ) continue; + sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff]; + if( sum + + +#define CPPSQLITE_ERROR 1000 + +class CppSQLite3Exception +{ +public: + + CppSQLite3Exception(const int nErrCode, + char* szErrMess, + bool bDeleteMsg=true); + + CppSQLite3Exception(const CppSQLite3Exception& e); + + virtual ~CppSQLite3Exception(); + + const int errorCode() { return mnErrCode; } + + const char* errorMessage() { return mpszErrMess; } + + static const char* errorCodeAsString(int nErrCode); + +private: + + int mnErrCode; + char* mpszErrMess; +}; + + +class CppSQLite3Buffer +{ +public: + + CppSQLite3Buffer(); + + ~CppSQLite3Buffer(); + + const char* format(const char* szFormat, ...); + + operator const char*() { return mpBuf; } + + void clear(); + +private: + + char* mpBuf; +}; + + +class CppSQLite3Binary +{ +public: + + CppSQLite3Binary(); + + ~CppSQLite3Binary(); + + void setBinary(const unsigned char* pBuf, int nLen); + void setEncoded(const unsigned char* pBuf); + + const unsigned char* getEncoded(); + const unsigned char* getBinary(); + + int getBinaryLength(); + + unsigned char* allocBuffer(int nLen); + + void clear(); + +private: + + unsigned char* mpBuf; + int mnBinaryLen; + int mnBufferLen; + int mnEncodedLen; + bool mbEncoded; +}; + + +class CppSQLite3Query +{ +public: + + CppSQLite3Query(); + + CppSQLite3Query(const CppSQLite3Query& rQuery); + + CppSQLite3Query(sqlite3* pDB, + sqlite3_stmt* pVM, + bool bEof, + bool bOwnVM=true); + + CppSQLite3Query& operator=(const CppSQLite3Query& rQuery); + + virtual ~CppSQLite3Query(); + + int numFields(); + + int fieldIndex(const char* szField); + const char* fieldName(int nCol); + + const char* fieldDeclType(int nCol); + int fieldDataType(int nCol); + + const char* fieldValue(int nField); + const char* fieldValue(const char* szField); + + int getIntField(int nField, int nNullValue=0); + int getIntField(const char* szField, int nNullValue=0); + + sqlite_int64 getInt64Field(int nField, sqlite_int64 nNullValue=0); + sqlite_int64 getInt64Field(const char* szField, sqlite_int64 nNullValue=0); + + double getFloatField(int nField, double fNullValue=0.0); + double getFloatField(const char* szField, double fNullValue=0.0); + + const char* getStringField(int nField, const char* szNullValue=""); + const char* getStringField(const char* szField, const char* szNullValue=""); + + const unsigned char* getBlobField(int nField, int& nLen); + const unsigned char* getBlobField(const char* szField, int& nLen); + + bool fieldIsNull(int nField); + bool fieldIsNull(const char* szField); + + bool eof(); + + void nextRow(); + + void finalize(); + +private: + + void checkVM(); + + sqlite3* mpDB; + sqlite3_stmt* mpVM; + bool mbEof; + int mnCols; + bool mbOwnVM; +}; + + +class CppSQLite3Table +{ +public: + + CppSQLite3Table(); + + CppSQLite3Table(const CppSQLite3Table& rTable); + + CppSQLite3Table(char** paszResults, int nRows, int nCols); + + virtual ~CppSQLite3Table(); + + CppSQLite3Table& operator=(const CppSQLite3Table& rTable); + + int numFields(); + + int numRows(); + + const char* fieldName(int nCol); + + const char* fieldValue(int nField); + const char* fieldValue(const char* szField); + + int getIntField(int nField, int nNullValue=0); + int getIntField(const char* szField, int nNullValue=0); + + double getFloatField(int nField, double fNullValue=0.0); + double getFloatField(const char* szField, double fNullValue=0.0); + + const char* getStringField(int nField, const char* szNullValue=""); + const char* getStringField(const char* szField, const char* szNullValue=""); + + bool fieldIsNull(int nField); + bool fieldIsNull(const char* szField); + + void setRow(int nRow); + + void finalize(); + +private: + + void checkResults(); + + int mnCols; + int mnRows; + int mnCurrentRow; + char** mpaszResults; +}; + + +class CppSQLite3Statement +{ +public: + + CppSQLite3Statement(); + + CppSQLite3Statement(const CppSQLite3Statement& rStatement); + + CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM); + + virtual ~CppSQLite3Statement(); + + CppSQLite3Statement& operator=(const CppSQLite3Statement& rStatement); + + int execDML(); + + CppSQLite3Query execQuery(); + + void bind(int nParam, const char* szValue); + void bind(int nParam, const int nValue); + void bind(int nParam, const double dwValue); + void bind(int nParam, const unsigned char* blobValue, int nLen); + void bindNull(int nParam); + + int bindParameterIndex(const char* szParam); + void bind(const char* szParam, const char* szValue); + void bind(const char* szParam, const int nValue); + void bind(const char* szParam, const double dwValue); + void bind(const char* szParam, const unsigned char* blobValue, int nLen); + void bindNull(const char* szParam); + + void reset(); + + void finalize(); + +private: + + void checkDB(); + void checkVM(); + + sqlite3* mpDB; + sqlite3_stmt* mpVM; +}; + + +class CppSQLite3DB +{ +public: + + CppSQLite3DB(); + + virtual ~CppSQLite3DB(); + + void open(const char* szFile); + + void close(); + + bool tableExists(const char* szTable); + + int execDML(const char* szSQL); + + CppSQLite3Query execQuery(const char* szSQL); + + int execScalar(const char* szSQL, int nNullValue=0); + + CppSQLite3Table getTable(const char* szSQL); + + CppSQLite3Statement compileStatement(const char* szSQL); + + sqlite_int64 lastRowId(); + + void interrupt() { sqlite3_interrupt(mpDB); } + + void setBusyTimeout(int nMillisecs); + + static const char* SQLiteVersion() { return SQLITE_VERSION; } + static const char* SQLiteHeaderVersion() { return SQLITE_VERSION; } + static const char* SQLiteLibraryVersion() { return sqlite3_libversion(); } + static int SQLiteLibraryVersionNumber() { return sqlite3_libversion_number(); } + + bool IsAutoCommitOn(); + +private: + + CppSQLite3DB(const CppSQLite3DB& db); + CppSQLite3DB& operator=(const CppSQLite3DB& db); + + sqlite3_stmt* compile(const char* szSQL); + + void checkDB(); + + sqlite3* mpDB; + int mnBusyTimeoutMs; +}; + + diff --git a/LicServer/DbLicServerFiller.cpp b/LicServer/DbLicServerFiller.cpp new file mode 100644 index 0000000..fb520c0 --- /dev/null +++ b/LicServer/DbLicServerFiller.cpp @@ -0,0 +1,367 @@ +#include "StdAfx.h" +#include "DbLicServerFiller.h" +#define MODULO "DbLicServerFiller" +#include "_log.h" +#include "Licencia.h" +#include "CppSQLite3.h" +#define PATH_DB_LS "serverversionmanager.db" +#include +#include +DbLicServerFiller *DbLicServerFiller::_instance=NULL; + +DbLicServerFiller::DbLicServerFiller(void) +{ +} + +DbLicServerFiller::~DbLicServerFiller(void) +{ +} + +DbLicServerFiller* DbLicServerFiller::Get() +{ + if(!_instance) + { + _instance = new DbLicServerFiller(); + if(!_instance->init()) + C_log::log(MODULO, "Error al inicializar db"); + } + return _instance; +} + +__int64 strToint64(const char* str) +{ + char st[32]; + int j =0; + int state =0;//0 año, 1 mes 2 dia, 3 hora, 4 min, 5 seg + int a=0,m=0,d=0,h =0,min=0,s=0, aux; + for(int i =0; str[i]!=0 && state<6; i++) + { + if(str[i]== ':'|| str[i]== '-' || str[i]== ' ') + { + st[j]=0; + j=0; + aux = atoi(st); + switch(state) + { + case(0): + a =aux; + break; + case(1): + m =aux; + break; + case(2): + d =aux; + break; + case(3): + h =aux; + break; + case(4): + min =aux; + break; + case(5): + s =aux; + break; + } + state++; + continue; + } + st[j++]=str[i]; + } + + CTime t = CTime(a,m,d,h,m,s); + return t.GetTime(); +} + +bool DbLicServerFiller::fill( Licencia* lic ) +{ + if(!db) + return FALSE; + std::string sql_select,caducidad; + bool res = false; + if(getProducId(lic)<0) + return false; + char s[32]; + sprintf(s,"%ld", lic->idProducto); + sql_select = "SELECT * from licencias WHERE clave = \""+std::string(lic->clave)+"\" AND id_producto = "+std::string(s); + + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + + while (!q.eof() && !res) + { + + lic->tipo = q.getIntField("tipo", 0); + lic->instaId = q.getIntField("id_instalador", -1); + lic->max_user = q.getIntField("user_max", 0); + + caducidad = q.getStringField("caducidad", ""); + lic->permisos = q.getIntField("permisos", 0); + lic->renovacion = q.getIntField("renovacion", 0); + lic->id = q.getIntField("id", -1); + + + res =true; + q.nextRow(); + } + q.finalize(); + if(!res) + return res; + lic->caducidad = strToint64(caducidad.c_str()); + + return res; +} + +int DbLicServerFiller::getProducId( Licencia* lic ) +{ + lic->idProducto = -1; + if(!db) + return lic->idProducto; + std::string sql_select,caducidad; + sql_select = "SELECT id from productos WHERE nombre = \""+std::string(lic->nombre_producto)+"\""; + + + + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + + while (!q.eof() && lic->idProducto<0) + { + lic->idProducto = q.getIntField("id", -1); + q.nextRow(); + } + q.finalize(); + return lic->idProducto; +} + +bool DbLicServerFiller::init() +{ + if (!PathFileExists(PATH_DB_LS)) + { + + C_log::log(MODULO, "Error no se encuentra archivo db: %s",PATH_DB_LS ); + return false; + } + try + { + db = new CppSQLite3DB(); + db->open(PATH_DB_LS); + } + catch (CppSQLite3Exception ex) + { + C_log::log(MODULO, "Error al arbrir db: %s",PATH_DB_LS ); + return false; + } + return true; +} + +int DbLicServerFiller::licCount( Licencia* lic ) +{ + if(!db || lic->id<0) + return -1; + + std::string sql_select,caducidad; + //pilla usuario + + int res = -1; + int idusu = -1; + CppSQLite3Query q; + + idusu =GetUsu(lic); + + + if(idusu<0) + return res; + res =0; + char ss[64]; + sprintf(ss,"%ld",lic->id); + sql_select = "SELECT id_usu FROM acceso WHERE id_licencia = "+std::string(ss); + q = db->execQuery(sql_select.c_str()); + while (!q.eof()) + { + res++; + if(idusu>=0 && idusu == q.getIntField("id_usu", -1)) + { + res =0; + q.finalize(); + return res; + } + } + q.finalize(); + return res; +} +int DbLicServerFiller::GetUsu( Licencia* lic ) +{ + if(!db) + return -1; + + std::string sql_select,caducidad; + //pilla usuario + sql_select = "SELECT * from usuarios WHERE idm = \""+std::string(lic->idm)+"\""; + int idusu = -1; + + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + + while (!q.eof() && idusu<0) + { + idusu= q.getIntField("id", -1); + break; + } + q.finalize(); + + if(idusu<0) + idusu =SetUsu(lic ); + + return idusu; +} + +int DbLicServerFiller::SetUsu( Licencia* lic ) +{ + if(!db || lic->instaId<=0) + return FALSE; + char ss[64]; + sprintf(ss,"%ld",lic->idCliente); + std::string sql_select,caducidad; + sql_select = "INSERT INTO usuarios (nombre, idm) "+ + std::string("VALUES (\"") + + std::string(lic->nombre_user)+"\", \""+ + std::string(lic->idm)+"\");"; + bool res = false; + int id_usu = -1; + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + res = q.eof(); + q.finalize(); + + if(!res) + return id_usu; + res = false; + sql_select = "SELECT id from usuarios WHERE idm = \""+std::string(lic->idm)+"\""; + q = db->execQuery(sql_select.c_str()); + + while (!q.eof() && !res) + { + id_usu = q.getIntField("id", -1); + + res =true; + q.nextRow(); + } + q.finalize(); + + return id_usu; +} + +bool DbLicServerFiller::fillInstal( Licencia* lic ) +{ + if(!db || lic->instaId<=0) + return FALSE; + std::string sql_select,caducidad; + char ss[64]; + sprintf(ss,"%ld",lic->instaId); + sql_select = "SELECT * from instaladores WHERE id = "+std::string(ss); + bool res = false; + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + + while (!q.eof() && !res) + { + strcpy(lic->instaServer,q.getStringField("server", "")); + strcpy(lic->instaKey,q.getStringField("clave", "")); + strcpy(lic->instaUsu,q.getStringField("usuario", "")); + + strcpy(lic->instaDescrip,q.getStringField("archivo_descripcion", "")); + strcpy(lic->instaPath,q.getStringField("archivo", "")); + strcpy(lic->instaVersion,q.getStringField("version", "")); + + + res =true; + q.nextRow(); + } + q.finalize(); + + return res; +} + +bool DbLicServerFiller::getConf( char *ip, int *port ) +{ + if(!db) + return FALSE; + std::string sql_select,fuelstate,str,sql_where; + + sql_select = "SELECT * from configuracion_socket"; + bool res = false; + + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + + while (!q.eof() || !res) + { + + *port = q.getIntField("puerto", -1); + strcpy(ip, q.getStringField("ip", "")); + res =true; + q.nextRow(); + } + q.finalize(); + return res; +} +bool DbLicServerFiller::setAcceso( Licencia* lic, __int64 *ultAcc, __int64 *actualAcceso) +{ + int idusua = GetUsu(lic); + if(!idusua) + return false; + //mira si existe + std::string sql_select; + char idusu[32]; + char idlic[32]; + char acces[32]; + CTime tiempo = CTime::GetCurrentTime(); + *actualAcceso=tiempo.GetTime(); + sprintf(acces,"%ld-%02d-%02d %02d:%02d %02d", + tiempo.GetYear(), tiempo.GetMonth(), tiempo.GetDay(), + tiempo.GetHour(), tiempo.GetMinute(), tiempo.GetSecond()); + sprintf(idusu, "%ld", idusua); + sprintf(idlic, "%ld", lic->id); + + sql_select = "SELECT * from acceso WHERE id_licencia = "+std::string(idusu) + + std::string(" AND id_usu = ")+std::string(idlic); + + bool res = false; + CppSQLite3Query q = db->execQuery(sql_select.c_str()); + std::string ultimo_acceso; + while (!q.eof() && !res) + { + ultimo_acceso = q.getStringField("ultimo_acceso", ""); + + //falta pillar acceso y version si existe + res =true; + q.nextRow(); + } + q.finalize(); + + if(res) + { + *ultAcc = strToint64(ultimo_acceso.c_str()); + //update acceso + + sql_select = "UPDATE acceso "+ + std::string("SET ultimo_acceso = \"") + acces + std::string("\", version = \"")+ + lic->version_producto+ std::string("\" ")+ + "WHERE id_usu = "+std::string(idusu)+ " AND id_licencia = "+std::string(idlic)+";"; + q = db->execQuery(sql_select.c_str()); + res = q.eof(); + q.finalize(); + return res; + } + else + { + *ultAcc =0; + //insert + sql_select = "INSERT INTO acceso (id_usu, id_licencia, ultimo_acceso, version) "+ + std::string("VALUES( ")+ + std::string(idusu)+", "+ + std::string(idlic)+", \""+ + std::string(acces)+"\", \""+ + std::string(lic->version_producto)+"\");"; + q = db->execQuery(sql_select.c_str()); + res = q.eof(); + q.finalize(); + return res; + + } + return false; +} diff --git a/LicServer/DbLicServerFiller.h b/LicServer/DbLicServerFiller.h new file mode 100644 index 0000000..d4c4808 --- /dev/null +++ b/LicServer/DbLicServerFiller.h @@ -0,0 +1,25 @@ +#pragma once +class CppSQLite3DB; +class DbLicServerFiller: public DBLicProvider +{ + CppSQLite3DB *db; + DbLicServerFiller(void); + static DbLicServerFiller* _instance; + bool init(); +public: + + ~DbLicServerFiller(void); + + virtual bool fill( Licencia* lic );//rellena datos licencia + virtual int licCount( Licencia* lic );//cuenta numero de licencias + virtual bool fillInstal( Licencia* lic );//rellena instalador + virtual bool setAcceso( Licencia* lic, __int64 *ultAcc, __int64 *actualAcceso); + virtual bool getConf( char *ip, int *port );//configuracion de escucha + + + static DbLicServerFiller* Get(); +private: + int SetUsu( Licencia* lic );//devuelve el id de usuario + int GetUsu( Licencia* lic );//crea usuario nuevo y devuelve el id + int getProducId( Licencia* lic ); +}; diff --git a/LicServer/LicServer.cpp b/LicServer/LicServer.cpp new file mode 100644 index 0000000..26a86e5 --- /dev/null +++ b/LicServer/LicServer.cpp @@ -0,0 +1,123 @@ +// LicServer.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "LicServer.h" +#include "DbLicServerFiller.h" +#include "_log.h" +#include "licencia.h" +#include "utl.h" +#include "StrArray.h" +#include "AppClasSrv.h" +#include "LicenciasManager.h" +#include "LicCliente.h" +#include "ClienteLicencias.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// The one and only application object + +CWinApp theApp; + +using namespace std; + +int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) +{ + int nRetCode = 0; + AppClasSrv app; + // initialize MFC and print and error on failure + if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) + { + // TODO: change error code to suit your needs + _tprintf(_T("Fatal Error: MFC initialization failed\n")); + nRetCode = 1; + } + else + { + if(argc==1) + { + ClienteLicencias lic; + if(!lic.cargaLicencia()) + C_log::log("Main", "Error al cargar licencia"); + C_log::log("Main", "Final feliz"); + system("pause"); + } + else if(argc==2 && strstr("Server",argv[1])) + { + //modo servidor-------------- + LicenciasManager licSrv; + if(licSrv.inicia(DbLicServerFiller::Get())) + { + C_log::log("Main", "Servidor activo"); + app.runApp(); + } + else + C_log::log("Main", "error iniciar servidor"); + + system("pause"); + + } + else if(argc>=2 && argc<=4 ) + { + LicCliente cli; + int tipo =0; + for (int i =1; ifill(&lic)) + C_log::log("Main", "error en acceder a bbdd"); + if(!filler->fillInstal(&lic)) + C_log::log("Main", "error en acceder a bbdd"); + __int64 accesodb, accesoAct; + if(!filler->setAcceso(&lic, &accesodb, &accesoAct)) + C_log::log("Main", "error en acceso a bbdd"); + int nlic =filler->licCount(&lic); + C_log::log("Main", "error en acceso a bbdd"); + lic.permisos = lic.permisos;*/ + } + + + } + + return nRetCode; +} diff --git a/LicServer/LicServer.h b/LicServer/LicServer.h new file mode 100644 index 0000000..d00d47e --- /dev/null +++ b/LicServer/LicServer.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/LicServer/LicServer.rc b/LicServer/LicServer.rc new file mode 100644 index 0000000..e643a03 --- /dev/null +++ b/LicServer/LicServer.rc @@ -0,0 +1,125 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "LicServer" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Spanish resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESN) +#ifdef _WIN32 +LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0c0a04b0" + BEGIN + VALUE "CompanyName", "Narvaling" + VALUE "FileDescription", "Servidor del gestor de Licencias" + VALUE "FileVersion", "1.0.0.1" + VALUE "InternalName", "LicServer" + VALUE "LegalCopyright", "(c) Narvaling. All rights reserved." + VALUE "OriginalFilename", "LicServer.exe" + VALUE "ProductName", "LicServer" + VALUE "ProductVersion", "1.0.0.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc0a, 1200 + END +END + +#endif // Spanish resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/LicServer/LicServer.vcxproj b/LicServer/LicServer.vcxproj new file mode 100644 index 0000000..341f3eb --- /dev/null +++ b/LicServer/LicServer.vcxproj @@ -0,0 +1,250 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D22EED4D-CE8E-4310-9C3A-DC7DE0368623} + LicServer + Win32Proj + + + + Application + v141 + Dynamic + MultiByte + true + + + Application + v141 + Dynamic + MultiByte + + + Application + v141 + Dynamic + MultiByte + true + + + Application + v141 + Dynamic + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 + + + $(Configuration)\ + $(Configuration)\ + true + + + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + $(Configuration)\ + $(Configuration)\ + false + + + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + + + + Disabled + ..\..\licUtiles;..\..\sqlite3;..\..\utiles;..\..\ClientLic;..\..\TransferSrv\FileTransfer;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + + + LicUtiles.lib;sqlite3.lib;Utiles.lib;ClientLic.lib;%(AdditionalDependencies) + ..\..\..\lib\$(Configuration);%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy $(OutDir)$(TargetFileName) ..\..\bin\$(IntDir) +copy ..\serverversionmanager.db ..\..\bin\$(IntDir) + + + + + X64 + + + Disabled + ..\..\licUtiles;..\..\sqlite3;..\..\utiles;..\..\ClientLic;..\..\TransferSrv\FileTransfer;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + ProgramDatabase + + + LicUtiles.lib;sqlite3.lib;Utiles.lib;ClientLic.lib;%(AdditionalDependencies) + ..\..\..\lib\x64\$(Configuration);%(AdditionalLibraryDirectories) + true + Console + MachineX64 + + + copy $(OutDir)$(TargetFileName) ..\..\bin\$(IntDir) +copy ..\serverversionmanager.db ..\..\bin\$(IntDir) + + + + + MaxSpeed + true + ..\..\licUtiles;..\..\sqlite3;..\..\utiles;..\..\ClientLic;..\..\TransferSrv\FileTransfer;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + Level3 + ProgramDatabase + + + LicUtiles.lib;sqlite3.lib;Utiles.lib;ClientLic.lib;%(AdditionalDependencies) + ..\..\..\lib\$(Configuration);%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy $(OutDir)$(TargetFileName) ..\..\bin\$(IntDir) +copy ..\serverversionmanager.db ..\..\bin\$(IntDir) + + + + + X64 + + + MaxSpeed + true + ..\..\licUtiles;..\..\sqlite3;..\..\utiles;..\..\ClientLic;..\..\TransferSrv\FileTransfer;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + Level3 + ProgramDatabase + + + LicUtiles.lib;sqlite3.lib;Utiles.lib;ClientLic.lib;%(AdditionalDependencies) + ..\..\..\lib\x64\$(Configuration);%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX64 + + + copy $(OutDir)$(TargetFileName) ..\..\bin\$(IntDir) +copy ..\serverversionmanager.db ..\..\bin\$(IntDir) + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + {22eeee5a-0a71-4655-b57f-5fb8e1692389} + false + + + {04e5b10e-5a75-48a2-857b-805659c7877d} + false + + + {149e3d49-90f8-44e6-a4f9-bdee84f65a70} + false + + + {30c05365-2dfc-4ad4-905e-8a414ae0d0a0} + false + + + {aa58c828-7025-4a4c-868e-76b8902af6bb} + false + + + + + + \ No newline at end of file diff --git a/LicServer/LicServer.vcxproj.filters b/LicServer/LicServer.vcxproj.filters new file mode 100644 index 0000000..4cbdea7 --- /dev/null +++ b/LicServer/LicServer.vcxproj.filters @@ -0,0 +1,65 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + + \ No newline at end of file diff --git a/LicServer/LicServer.vcxproj.user b/LicServer/LicServer.vcxproj.user new file mode 100644 index 0000000..be25078 --- /dev/null +++ b/LicServer/LicServer.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LicServer/ReadMe.txt b/LicServer/ReadMe.txt new file mode 100644 index 0000000..f44d9ff --- /dev/null +++ b/LicServer/ReadMe.txt @@ -0,0 +1,46 @@ +======================================================================== + CONSOLE APPLICATION : LicServer Project Overview +======================================================================== + +AppWizard has created this LicServer application for you. + +This file contains a summary of what you will find in each of the files that +make up your LicServer application. + + +LicServer.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +LicServer.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +AppWizard has created the following resources: + +LicServer.rc + This is a listing of all of the Microsoft Windows resources that the + program uses. It includes the icons, bitmaps, and cursors that are stored + in the RES subdirectory. This file can be directly edited in Microsoft + Visual C++. + +Resource.h + This is the standard header file, which defines new resource IDs. + Microsoft Visual C++ reads and updates this file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named LicServer.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/LicServer/Resource.h b/LicServer/Resource.h new file mode 100644 index 0000000..ea01251 --- /dev/null +++ b/LicServer/Resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by LicServer.rc +// + +#define IDS_APP_TITLE 103 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/LicServer/stdafx.cpp b/LicServer/stdafx.cpp new file mode 100644 index 0000000..22cf583 --- /dev/null +++ b/LicServer/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// LicServer.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/LicServer/stdafx.h b/LicServer/stdafx.h new file mode 100644 index 0000000..e6adb01 --- /dev/null +++ b/LicServer/stdafx.h @@ -0,0 +1,33 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +#include +#include // MFC core and standard components +#include // MFC extensions +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC support for Internet Explorer 4 Common Controls +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include + +#include "LicUtilesDef.h" +#include "base_head.h" + +// TODO: reference additional headers your program requires here diff --git a/LicServer/targetver.h b/LicServer/targetver.h new file mode 100644 index 0000000..203dfbc --- /dev/null +++ b/LicServer/targetver.h @@ -0,0 +1,24 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. +#endif diff --git a/Release/FileTransfer.dll b/Release/FileTransfer.dll new file mode 100644 index 0000000..b7068b9 Binary files /dev/null and b/Release/FileTransfer.dll differ diff --git a/Release/FileTransfer.exp b/Release/FileTransfer.exp new file mode 100644 index 0000000..eca5a7e Binary files /dev/null and b/Release/FileTransfer.exp differ diff --git a/Release/FileTransfer.iobj b/Release/FileTransfer.iobj new file mode 100644 index 0000000..7d225fb Binary files /dev/null and b/Release/FileTransfer.iobj differ diff --git a/Release/FileTransfer.ipdb b/Release/FileTransfer.ipdb new file mode 100644 index 0000000..099cf97 Binary files /dev/null and b/Release/FileTransfer.ipdb differ diff --git a/Release/FileTransfer.lib b/Release/FileTransfer.lib new file mode 100644 index 0000000..6eca62d Binary files /dev/null and b/Release/FileTransfer.lib differ diff --git a/Release/FileTransfer.pdb b/Release/FileTransfer.pdb new file mode 100644 index 0000000..99f2e10 Binary files /dev/null and b/Release/FileTransfer.pdb differ diff --git a/Release/TransferSrv.exe b/Release/TransferSrv.exe new file mode 100644 index 0000000..fda80a5 Binary files /dev/null and b/Release/TransferSrv.exe differ diff --git a/Release/TransferSrv.iobj b/Release/TransferSrv.iobj new file mode 100644 index 0000000..b2f54dd Binary files /dev/null and b/Release/TransferSrv.iobj differ diff --git a/Release/TransferSrv.ipdb b/Release/TransferSrv.ipdb new file mode 100644 index 0000000..90d872d Binary files /dev/null and b/Release/TransferSrv.ipdb differ diff --git a/Release/TransferSrv.pdb b/Release/TransferSrv.pdb new file mode 100644 index 0000000..9b1dec2 Binary files /dev/null and b/Release/TransferSrv.pdb differ diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 0000000..6bed8cf Binary files /dev/null and b/UpgradeLog.htm differ diff --git a/limpia.bat b/limpia.bat new file mode 100644 index 0000000..fa770d9 --- /dev/null +++ b/limpia.bat @@ -0,0 +1,25 @@ +@echo off +Echo Borra ncb. +del "%~dp0"\*.ncb +Echo Borra bak +del "%~dp0"\*.bak + +Echo Borra aps +del "%~dp0"\*.aps + +Echo Borra debug. +rmdir /s /q "%~dp0"\debug" + +Echo Borra release. +rmdir /s /q "%~dp0"\release + + +rmdir /s /q "%~dp0"\x64" +rmdir /s /q "%~dp0"\LicServer\debug" +rmdir /s /q "%~dp0"\LicServer\release" +rmdir /s /q "%~dp0"\LicServer\x64" + + + + +pause \ No newline at end of file diff --git a/serverversionmanager.db b/serverversionmanager.db new file mode 100644 index 0000000..b24fcfb Binary files /dev/null and b/serverversionmanager.db differ diff --git a/serverversionmanager_.db b/serverversionmanager_.db new file mode 100644 index 0000000..20dd0f4 Binary files /dev/null and b/serverversionmanager_.db differ