Versione 12
git-svn-id: svn://10.65.10.50/branches/R_10_00@23098 c028cbd2-c16b-5b4b-a496-9718f37d4682
@ -31,6 +31,9 @@
|
|||||||
// Displayed name of the service
|
// Displayed name of the service
|
||||||
#define SERVICE_DISPLAY_NAME TEXT("Sirio Digital signature service")
|
#define SERVICE_DISPLAY_NAME TEXT("Sirio Digital signature service")
|
||||||
|
|
||||||
|
// Service start options.
|
||||||
|
#define SERVICE_TYPE SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS
|
||||||
|
|
||||||
// Service start options.
|
// Service start options.
|
||||||
#define SERVICE_START_TYPE SERVICE_AUTO_START
|
#define SERVICE_START_TYPE SERVICE_AUTO_START
|
||||||
|
|
||||||
@ -38,7 +41,8 @@
|
|||||||
#define SERVICE_DEPENDENCIES TEXT("")
|
#define SERVICE_DEPENDENCIES TEXT("")
|
||||||
|
|
||||||
// The name of the account under which the service should run
|
// The name of the account under which the service should run
|
||||||
#define SERVICE_ACCOUNT TEXT("NT AUTHORITY\\LocalService")
|
//#define SERVICE_ACCOUNT TEXT("NT AUTHORITY\\LocalService")
|
||||||
|
#define SERVICE_ACCOUNT NULL
|
||||||
|
|
||||||
// The password to the service account name
|
// The password to the service account name
|
||||||
#define SERVICE_PASSWORD NULL
|
#define SERVICE_PASSWORD NULL
|
||||||
@ -65,16 +69,18 @@ int wmain(int argc, wchar_t *argv[])
|
|||||||
{
|
{
|
||||||
if (_wcsicmp(L"install", argv[1] + 1) == 0)
|
if (_wcsicmp(L"install", argv[1] + 1) == 0)
|
||||||
{
|
{
|
||||||
InstallService(
|
if (InstallService(
|
||||||
SERVICE_NAME, // Name of service
|
SERVICE_NAME, // Name of service
|
||||||
SERVICE_DISPLAY_NAME, // Name to display
|
SERVICE_DISPLAY_NAME, // Name to display
|
||||||
|
SERVICE_TYPE, // Service type
|
||||||
SERVICE_START_TYPE, // Service start type
|
SERVICE_START_TYPE, // Service start type
|
||||||
SERVICE_DEPENDENCIES, // Dependencies
|
SERVICE_DEPENDENCIES, // Dependencies
|
||||||
SERVICE_ACCOUNT, // Service running account
|
SERVICE_ACCOUNT, // Service running account
|
||||||
SERVICE_PASSWORD // Password of the account
|
SERVICE_PASSWORD // Password of the account
|
||||||
);
|
))
|
||||||
|
StartService(SERVICE_NAME);
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"remove", argv[1] + 1) == 0)
|
else if (_wcsicmp(L"remove", argv[1] + 1) == 0 || _wcsicmp(L"uninstall", argv[1] + 1) == 0)
|
||||||
{
|
{
|
||||||
UninstallService(SERVICE_NAME);
|
UninstallService(SERVICE_NAME);
|
||||||
}
|
}
|
||||||
@ -98,8 +104,9 @@ int wmain(int argc, wchar_t *argv[])
|
|||||||
CESignService service(SERVICE_NAME);
|
CESignService service(SERVICE_NAME);
|
||||||
if (!CServiceBase::Run(service))
|
if (!CServiceBase::Run(service))
|
||||||
{
|
{
|
||||||
wprintf(L"Parameters: -install -start -stop -restart -remove\n");
|
printf("ESignService 1.4 %s\n", __TIMESTAMP__);
|
||||||
wprintf(L"Running as standard process from command line\n");
|
printf("Parameters: -install -start -stop -restart -remove\n");
|
||||||
|
printf("Running as standard process from command line\n");
|
||||||
service.ServiceLoop();
|
service.ServiceLoop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,341 +2,33 @@
|
|||||||
#include "ESignService.h"
|
#include "ESignService.h"
|
||||||
#include "ThreadPool.h"
|
#include "ThreadPool.h"
|
||||||
|
|
||||||
#include "esigner.h"
|
#include "PathName.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
#include <zmq.h>
|
#include <zmq.h>
|
||||||
|
|
||||||
|
#include <Wtsapi32.h>
|
||||||
|
#pragma comment(lib, "Wtsapi32.lib")
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Utility
|
// Utility
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static std::string GetIniString(const char* key)
|
static errno_t GetIniString(const char* key, gt_string val)
|
||||||
{
|
{
|
||||||
char val[_MAX_PATH];
|
::GetPrivateProfileStringA("Default", key, "", val, sizeof(gt_string), "./esigner.ini");
|
||||||
::GetPrivateProfileStringA("Default", key, "", val, sizeof(val), "./esigner.ini");
|
return *val ? 0 : EINVAL;
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetIniInteger(const char* key)
|
static int GetIniInteger(const char* key)
|
||||||
{
|
{
|
||||||
char val[_MAX_PATH];
|
gt_string val = { 0 };
|
||||||
::GetPrivateProfileStringA("Default", key, "", val, sizeof(val), "./esigner.ini");
|
GetIniString(key, val);
|
||||||
return atoi(val);
|
return atoi(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// CEsigner
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class CEsigner
|
|
||||||
{
|
|
||||||
HMODULE _hESigner;
|
|
||||||
ESignerSignProto _SignPDF;
|
|
||||||
ESignerVerifyProto _VerifyPDF;
|
|
||||||
bool m_bMark;
|
|
||||||
int m_nNum;
|
|
||||||
std::string m_strDLL, m_strPFX, m_strPEM, m_strCER, m_strEXT;
|
|
||||||
std::string m_strTSAurl, m_strTSAuser, m_strTSApwd, m_strTSApolicy, m_strTSAcoding;
|
|
||||||
std::string* _socket;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Log(const char* fmt, ...) const;
|
|
||||||
bool EsitoZero(const CPathName& strResult) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsOk() const { return _hESigner != NULL; }
|
|
||||||
|
|
||||||
void SetOutputString(std::string& s) { _socket = &s; }
|
|
||||||
bool Sign(const CPathName& strInput, CPathName& strOutput, const CPathName& strBackup,
|
|
||||||
const std::string& strPin, const std::string& strExt) const;
|
|
||||||
|
|
||||||
CEsigner();
|
|
||||||
virtual ~CEsigner();
|
|
||||||
};
|
|
||||||
|
|
||||||
void CEsigner::Log(const char* fmt, ...) const
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf_s(buffer, sizeof(buffer), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (_socket != NULL)
|
|
||||||
{
|
|
||||||
*_socket += buffer;
|
|
||||||
*_socket += "\r\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("%s\n", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
CEsigner::CEsigner() : m_bMark(false), m_nNum(0), _socket(NULL)
|
|
||||||
{
|
|
||||||
char full[_MAX_PATH]; ::GetModuleFileNameA(NULL, full, sizeof(full));
|
|
||||||
CPathName pn = full;
|
|
||||||
::SetCurrentDirectoryA(pn.Path().c_str());
|
|
||||||
|
|
||||||
_hESigner = ::LoadLibrary(TEXT("esigner.dll"));
|
|
||||||
if (_hESigner)
|
|
||||||
{
|
|
||||||
_SignPDF = (ESignerSignProto)::GetProcAddress(_hESigner, "Sign");
|
|
||||||
_VerifyPDF = (ESignerVerifyProto)::GetProcAddress(_hESigner, "Verify");
|
|
||||||
m_strCER = GetIniString("CER");
|
|
||||||
m_strDLL = GetIniString("DLL");
|
|
||||||
m_strPEM = GetIniString("PEM");
|
|
||||||
m_strPFX = GetIniString("PFX");
|
|
||||||
m_strEXT = GetIniString("EXT"); // PDF or P7M
|
|
||||||
if (m_strEXT.empty())
|
|
||||||
m_strEXT = "p7m";
|
|
||||||
|
|
||||||
const int nIdx = GetIniInteger("IDX");
|
|
||||||
if (nIdx > 0)
|
|
||||||
m_nNum = nIdx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CEsigner::~CEsigner()
|
|
||||||
{
|
|
||||||
if (_hESigner)
|
|
||||||
::FreeLibrary(_hESigner);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CEsigner::EsitoZero(const CPathName& strResult) const
|
|
||||||
{
|
|
||||||
bool positive = false;
|
|
||||||
FILE* f = NULL;
|
|
||||||
if (fopen_s(&f, strResult.c_str(), "r") == 0)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
while (!feof(f))
|
|
||||||
{
|
|
||||||
fgets(buffer, sizeof(buffer), f);
|
|
||||||
if (strstr(buffer, "ESITO=\"000\"") != NULL)
|
|
||||||
{
|
|
||||||
positive = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return positive;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CEsigner::Sign(const CPathName& strInput, CPathName& strOutput, const CPathName& strBackup,
|
|
||||||
const std::string& strPin, const std::string& strExt) const
|
|
||||||
{
|
|
||||||
if (_hESigner == NULL)
|
|
||||||
{
|
|
||||||
Log("Impossibile caricare esigner.dll");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string strMethod;
|
|
||||||
if (!m_strDLL.empty()) // Token
|
|
||||||
{
|
|
||||||
strMethod = "T";
|
|
||||||
Log("Firma tramite token");
|
|
||||||
} else
|
|
||||||
if (!m_strPFX.empty())
|
|
||||||
{
|
|
||||||
strMethod = "P";
|
|
||||||
Log("Firma tramite file PFX");
|
|
||||||
} else
|
|
||||||
if (!m_strCER.empty())
|
|
||||||
{
|
|
||||||
strMethod = "F";
|
|
||||||
Log("Firma tramite i file CER e PEM");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log("Impossibile trovare certificati o token.\nVerificare i parametri in esigner.ini");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string strOperation = "S";
|
|
||||||
|
|
||||||
const bool bIsTSA = m_bMark && !m_strTSAurl.empty();
|
|
||||||
if (bIsTSA) // Firma con marcatura temporale
|
|
||||||
strOperation += "+T";
|
|
||||||
|
|
||||||
const bool bIsDir = strInput.IsDirectory();
|
|
||||||
if (bIsDir)
|
|
||||||
strOperation += "+D";
|
|
||||||
|
|
||||||
std::string strIndex;
|
|
||||||
strIndex << m_nNum;
|
|
||||||
|
|
||||||
char* operation = (char*)strOperation.c_str();
|
|
||||||
char* method = (char*)strMethod.c_str();
|
|
||||||
char* ext = (char*)(strExt.empty() ? m_strEXT.c_str() : strExt.c_str());
|
|
||||||
char* input = (char*)strInput.c_str();
|
|
||||||
char* output = (char*)strOutput.c_str();
|
|
||||||
|
|
||||||
char* cer = strMethod == "F" ? (char*)m_strCER.c_str() : NULL;
|
|
||||||
char* pem = strMethod == "F" ? (char*)m_strPEM.c_str() : NULL;
|
|
||||||
char* pfx = strMethod == "P" ? (char*)m_strPFX.c_str() : NULL;
|
|
||||||
char* idx = (char*)strIndex.c_str();
|
|
||||||
char* pin = (char*)strPin.c_str();
|
|
||||||
char* dll = strMethod == "T" ? (char*)m_strDLL.c_str() : NULL;
|
|
||||||
|
|
||||||
char* TSA_output = NULL;
|
|
||||||
char* TSA_url = NULL;
|
|
||||||
char* TSA_user = NULL;
|
|
||||||
char* TSA_pwd = NULL;
|
|
||||||
char* TSA_policy = NULL;
|
|
||||||
char* TSA_coding = NULL;
|
|
||||||
char* TSA_rootCA = NULL;
|
|
||||||
|
|
||||||
if (bIsTSA) // Firma con marcatura temporale
|
|
||||||
{
|
|
||||||
TSA_url = (char*)m_strTSAurl.c_str();
|
|
||||||
TSA_user = (char*)m_strTSAuser.c_str();
|
|
||||||
TSA_pwd = (char*)m_strTSApwd.c_str();
|
|
||||||
TSA_policy = (char*)m_strTSApolicy.c_str();
|
|
||||||
TSA_coding = (char*)m_strTSAcoding.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bIsDir)
|
|
||||||
{
|
|
||||||
if (strOutput.empty())
|
|
||||||
output = input;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//ext = strInput.Lower().EndsWith(".pdf") ? ".pdf.p7m" : ".p7m";
|
|
||||||
if (strOutput.empty())
|
|
||||||
{
|
|
||||||
strOutput = strInput;
|
|
||||||
if (strExt == "p7m")
|
|
||||||
strOutput += ".p7m";
|
|
||||||
}
|
|
||||||
::DeleteFileA(strOutput.c_str()); // Altrimenti la fantastica dll s'incazza come una biscia
|
|
||||||
|
|
||||||
while (!strOutput.Ext().empty())
|
|
||||||
strOutput.SetExt("");
|
|
||||||
output = (char*)strOutput.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = _SignPDF(operation, method,
|
|
||||||
input, output, NULL, ext,
|
|
||||||
cer, pem, pfx, dll, pin, NULL, idx,
|
|
||||||
TSA_url, TSA_user, TSA_pwd, TSA_policy, TSA_coding, NULL);
|
|
||||||
|
|
||||||
int nSigned = 0;
|
|
||||||
if (bIsDir) // +D only
|
|
||||||
{
|
|
||||||
std::vector<CPathName> infiles;
|
|
||||||
CPathName pnInput; pnInput.Set(strInput.c_str(), "*", "pdf");
|
|
||||||
const size_t n = pnInput.List(infiles);
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
Log("Trovati %d documenti da firmare in %s", n, strInput.c_str());
|
|
||||||
|
|
||||||
res = 0;
|
|
||||||
CPathName pnResult;
|
|
||||||
for (size_t i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
const CPathName& fi = infiles[i];
|
|
||||||
pnResult.Set(strOutput.c_str(), fi.FullName().c_str(), "result");
|
|
||||||
if (pnResult.IsFile() && EsitoZero(pnResult))
|
|
||||||
{
|
|
||||||
::DeleteFileA(pnResult.c_str());
|
|
||||||
nSigned++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log("Impossibile firmare il file %s", fi.c_str());
|
|
||||||
res = -99;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mode = 0; // 0=nulla; 1=cancella; 2=backup
|
|
||||||
if (strBackup == "Cestino" || strBackup == "NULL" || strBackup == "Delete" ||
|
|
||||||
strBackup == "Basket" || strBackup == "Trash")
|
|
||||||
mode = 1; else
|
|
||||||
if (strBackup.IsDirectory())
|
|
||||||
mode = 2;
|
|
||||||
|
|
||||||
if (res == 0 && mode != 0 && n > 0)
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
if (mode == 1)
|
|
||||||
{
|
|
||||||
msg = "Eliminazione file originali in ";
|
|
||||||
msg += strInput;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg = "Spostamento file originali da ";
|
|
||||||
msg += strInput;
|
|
||||||
msg += " a ";
|
|
||||||
msg += strBackup;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
const CPathName& fsrc = infiles[i];
|
|
||||||
CPathName fout = fsrc;
|
|
||||||
fout.SetPath(strBackup.c_str());
|
|
||||||
if (mode == 2)
|
|
||||||
::MoveFileA(fsrc.c_str(), fout.c_str());
|
|
||||||
else
|
|
||||||
::DeleteFileA(fsrc.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log("Un documento da firmare in %s", strInput.c_str());
|
|
||||||
nSigned == res ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == 0)
|
|
||||||
{
|
|
||||||
if (nSigned > 0)
|
|
||||||
Log("Sono stati firmati %d documenti in %s", nSigned, output);
|
|
||||||
else
|
|
||||||
Log("Non è stato firmato alcun documento");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char* msg = NULL;
|
|
||||||
switch (res)
|
|
||||||
{
|
|
||||||
case -2: msg = "Errore di lettura del certificato"; break;
|
|
||||||
case -3: msg = "Errore di lettura della chiave privata"; break;
|
|
||||||
case -4: msg = "Errore di lettura file PFX"; break;
|
|
||||||
case -5: msg = "Errore recupero certificato da Token"; break;
|
|
||||||
case -6: msg = "Errore apertura file"; break;
|
|
||||||
case -7:
|
|
||||||
case -8:
|
|
||||||
case -9: msg = "Errore conatatto TSA"; break;
|
|
||||||
case -10: msg = "Accesso al token fallito"; break;
|
|
||||||
case -11: msg = "Impossibile trovare dll driver del token"; break;
|
|
||||||
case -14: msg = "Il file di output esiste già"; break;
|
|
||||||
case -15:
|
|
||||||
case -16: msg = "Errore di marcatura temporale"; break;
|
|
||||||
case -99: msg = "Impossibile trovare .result per tutti i file della cartella"; break;
|
|
||||||
default : msg = "Errore di accesso alle operazioni di firma"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// CESignService
|
// CESignService
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
@ -405,35 +97,48 @@ char CESignService::ParseHex(const char* hex) const
|
|||||||
return char(n);
|
return char(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* CESignService::ParseString(const char* equal, std::string& str) const
|
const char* CESignService::ParseString(const char* equal, gt_string str) const
|
||||||
{
|
{
|
||||||
str = "";
|
gt_strcpy(str, "");
|
||||||
const char* s = equal;
|
const char* s = equal;
|
||||||
|
int i = 0;
|
||||||
for (; *s != '&' && *s > ' '; s++)
|
for (; *s != '&' && *s > ' '; s++)
|
||||||
{
|
{
|
||||||
if (*s == '%')
|
if (*s == '%')
|
||||||
{
|
{
|
||||||
const char h = ParseHex(s+1);
|
const char h = ParseHex(s+1);
|
||||||
str += h;
|
gt_chrcat(str, h);
|
||||||
s += 2;
|
s += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
str += *s;
|
gt_chrcat(str, *s);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* CESignService::ParseString(const char* equal, CPathName& path) const
|
||||||
|
{
|
||||||
|
gt_string str = { 0 };
|
||||||
|
const char* s = ParseString(equal, str);
|
||||||
|
path.Set(str);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CESignService::ParseGET(const char* get, CPathName& src, CPathName& dst, CPathName& bck,
|
bool CESignService::ParseGET(const char* get, CPathName& src, CPathName& dst, CPathName& bck,
|
||||||
std::string& pin, std::string& ext) const
|
gt_string pin, gt_string ext) const
|
||||||
{
|
{
|
||||||
src = dst = bck = "";
|
src = dst = bck = "";
|
||||||
pin = "";
|
gt_strcpy(pin, "");
|
||||||
ext = "";
|
gt_strcpy(ext, "");
|
||||||
while (get != NULL)
|
while (get != NULL)
|
||||||
{
|
{
|
||||||
const char* equal = strchr(get, '=');
|
const char* equal = strchr(get, '=');
|
||||||
if (equal != NULL)
|
if (equal != NULL)
|
||||||
{
|
{
|
||||||
|
if (*(equal-1) > 'Z')
|
||||||
|
break;
|
||||||
|
|
||||||
switch (*(equal-3))
|
switch (*(equal-3))
|
||||||
{
|
{
|
||||||
case 'B': get = ParseString(equal+1, bck); break; // BCK
|
case 'B': get = ParseString(equal+1, bck); break; // BCK
|
||||||
@ -441,7 +146,7 @@ bool CESignService::ParseGET(const char* get, CPathName& src, CPathName& dst, CP
|
|||||||
case 'E': get = ParseString(equal+1, ext); break; // EXT
|
case 'E': get = ParseString(equal+1, ext); break; // EXT
|
||||||
case 'P': get = ParseString(equal+1, pin); break; // PIN
|
case 'P': get = ParseString(equal+1, pin); break; // PIN
|
||||||
case 'S': get = ParseString(equal+1, src); break; // SRC
|
case 'S': get = ParseString(equal+1, src); break; // SRC
|
||||||
default : break;
|
default : get = equal+1; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -450,6 +155,107 @@ bool CESignService::ParseGET(const char* get, CPathName& src, CPathName& dst, CP
|
|||||||
return !src.empty();
|
return !src.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DWORD CESignService::RunAsync(const char* strCmdLine) const
|
||||||
|
{
|
||||||
|
DWORD ret = ::WinExec(strCmdLine, SW_SHOWDEFAULT);
|
||||||
|
|
||||||
|
if (ret >= 32)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LPWSTR messageBuffer = NULL;
|
||||||
|
ret = ::GetLastError();
|
||||||
|
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, ret, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
|
||||||
|
|
||||||
|
WriteEventLogEntry(messageBuffer, EVENTLOG_ERROR_TYPE, ret);
|
||||||
|
LocalFree(messageBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DWORD CESignService::RunSync(const char* strCmdLine) const
|
||||||
|
{
|
||||||
|
STARTUPINFOA si = { 0 };
|
||||||
|
PROCESS_INFORMATION pi = { 0 };
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
si.lpDesktop = "winsta0\\default";
|
||||||
|
si.wShowWindow = SW_SHOW;
|
||||||
|
|
||||||
|
DWORD activeSessionId = ::WTSGetActiveConsoleSessionId();
|
||||||
|
HANDLE currentToken = NULL; ::WTSQueryUserToken(activeSessionId, ¤tToken);
|
||||||
|
|
||||||
|
DWORD err = 0;
|
||||||
|
|
||||||
|
if (currentToken)
|
||||||
|
{
|
||||||
|
::CreateProcessAsUserA(currentToken, NULL,
|
||||||
|
(LPSTR)strCmdLine, // lpCommandLine
|
||||||
|
NULL, // lpProcessAttributes
|
||||||
|
NULL, // lpThreadAttributes
|
||||||
|
FALSE, // no Handle inheritance
|
||||||
|
NORMAL_PRIORITY_CLASS, // creation flags
|
||||||
|
NULL, // Use parent's environment block
|
||||||
|
NULL, // Use parent's starting directory
|
||||||
|
&si,
|
||||||
|
&pi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::CreateProcessA(NULL,
|
||||||
|
(LPSTR)strCmdLine, // lpCommandLine
|
||||||
|
NULL, // lpProcessAttributes
|
||||||
|
NULL, // lpThreadAttributes
|
||||||
|
FALSE, // no Handle inheritance
|
||||||
|
NORMAL_PRIORITY_CLASS, // creation flags
|
||||||
|
NULL, // Use parent's environment block
|
||||||
|
NULL, // Use parent's starting directory
|
||||||
|
&si,
|
||||||
|
&pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pi.hProcess)
|
||||||
|
{
|
||||||
|
::WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
::CloseHandle(pi.hProcess);
|
||||||
|
::CloseHandle(pi.hThread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = ::GetLastError();
|
||||||
|
|
||||||
|
if (currentToken)
|
||||||
|
{
|
||||||
|
::CloseHandle(currentToken);
|
||||||
|
currentToken = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AppendVar(gt_string cmd, const char* var, const char* val)
|
||||||
|
{
|
||||||
|
if (val && *val)
|
||||||
|
{
|
||||||
|
gt_chrcat(cmd, ' ');
|
||||||
|
gt_strcat(cmd, var);
|
||||||
|
gt_chrcat(cmd, '=');
|
||||||
|
if (*val != '"' && strchr(val, ' '))
|
||||||
|
{
|
||||||
|
gt_chrcat(cmd, '"');
|
||||||
|
gt_strcat(cmd, val);
|
||||||
|
gt_chrcat(cmd, '"');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gt_strcat(cmd, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// FUNCTION: CESignService::ServiceLoop(void)
|
// FUNCTION: CESignService::ServiceLoop(void)
|
||||||
//
|
//
|
||||||
@ -476,8 +282,9 @@ void CESignService::ServiceLoop(void)
|
|||||||
/* Data structure to hold the ZMQ_STREAM ID */
|
/* Data structure to hold the ZMQ_STREAM ID */
|
||||||
uint8_t id [256];
|
uint8_t id [256];
|
||||||
/* Data structure to hold the ZMQ_STREAM received data */
|
/* Data structure to hold the ZMQ_STREAM received data */
|
||||||
const size_t raw_max = 512;
|
const size_t raw_max = 1024;
|
||||||
char* raw = new char[raw_max];
|
char* raw = new char[raw_max];
|
||||||
|
|
||||||
while (!m_fStopping)
|
while (!m_fStopping)
|
||||||
{
|
{
|
||||||
/* Get HTTP request; ID frame and then request */
|
/* Get HTTP request; ID frame and then request */
|
||||||
@ -490,18 +297,59 @@ void CESignService::ServiceLoop(void)
|
|||||||
const size_t raw_size = zmq_recv (socket, raw, raw_max, 0);
|
const size_t raw_size = zmq_recv (socket, raw, raw_max, 0);
|
||||||
|
|
||||||
CPathName src, dst, bck;
|
CPathName src, dst, bck;
|
||||||
std::string pin, ext;
|
gt_string pin = { 0 }, ext = { 0 };
|
||||||
ParseGET(raw, src, dst, bck, pin, ext);
|
ParseGET(raw, src, dst, bck, pin, ext);
|
||||||
|
|
||||||
/* Sends the ID frame followed by the response */
|
/* Sends the ID frame followed by the response */
|
||||||
zmq_send (socket, id, id_size, ZMQ_SNDMORE);
|
zmq_send (socket, id, id_size, ZMQ_SNDMORE);
|
||||||
|
|
||||||
|
gt_string log = {0};
|
||||||
|
gt_strcpy(log, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n");
|
||||||
|
|
||||||
/* Prepares the response */
|
CPathName pdf; pdf.Set(src, "*", "pdf");
|
||||||
std::string log = "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
const int nTotal = pdf.Count();
|
||||||
CEsigner esigner;
|
|
||||||
esigner.SetOutputString(log);
|
if (nTotal > 0)
|
||||||
esigner.Sign(src, dst, bck, pin, ext);
|
{
|
||||||
zmq_send (socket, log.c_str(),log.length(), ZMQ_SNDMORE);
|
const char* const cmdfile = "ESignCmd.exe";
|
||||||
|
const char* const logfile = "ESignCmd.log";
|
||||||
|
gt_string cmd = { 0 };
|
||||||
|
gt_strcpy(cmd, cmdfile);
|
||||||
|
AppendVar(cmd, "SRC", src);
|
||||||
|
AppendVar(cmd, "DST", dst);
|
||||||
|
AppendVar(cmd, "BCK", bck);
|
||||||
|
AppendVar(cmd, "LOG", logfile);
|
||||||
|
AppendVar(cmd, "PIN", pin);
|
||||||
|
AppendVar(cmd, "EXT", ext);
|
||||||
|
|
||||||
|
const DWORD err = RunSync(cmd);
|
||||||
|
memset(raw, 0, raw_max);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
FILE* log = NULL;
|
||||||
|
if (fopen_s(&log, logfile, "r") == 0)
|
||||||
|
{
|
||||||
|
fread(raw, raw_max-1, 1, log);
|
||||||
|
fclose(log); log = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf_s(raw, raw_max,
|
||||||
|
"%s: bloccato nella firma di %d documenti.",
|
||||||
|
cmdfile, nTotal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf_s(raw, raw_max,
|
||||||
|
"%s: errore 0x%X nella firma di %d documenti.",
|
||||||
|
cmdfile, err, nTotal);
|
||||||
|
|
||||||
|
gt_strcat(log, raw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gt_strcat(log, "Non ci sono documenti da firmare!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
zmq_send (socket, log, strlen(log), ZMQ_SNDMORE);
|
||||||
|
|
||||||
/* Closes the connection by sending the ID frame followed by a zero response */
|
/* Closes the connection by sending the ID frame followed by a zero response */
|
||||||
zmq_send (socket, id, id_size, ZMQ_SNDMORE);
|
zmq_send (socket, id, id_size, ZMQ_SNDMORE);
|
||||||
@ -538,6 +386,6 @@ void CESignService::OnStop()
|
|||||||
// Indicate that the service is stopping and wait for the finish of the
|
// Indicate that the service is stopping and wait for the finish of the
|
||||||
// main service function (ServiceWorkerThread).
|
// main service function (ServiceWorkerThread).
|
||||||
m_fStopping = TRUE;
|
m_fStopping = TRUE;
|
||||||
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
if (::WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||||
throw GetLastError();
|
throw ::GetLastError();
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,13 @@ protected:
|
|||||||
virtual void OnStop();
|
virtual void OnStop();
|
||||||
|
|
||||||
char ParseHex(const char* hex) const;
|
char ParseHex(const char* hex) const;
|
||||||
const char* ParseString(const char* s, std::string& str) const;
|
const char* ParseString(const char* s, gt_string str) const;
|
||||||
|
const char* ParseString(const char* equal, CPathName& path) const;
|
||||||
bool ParseGET(const char* get, CPathName& src, CPathName& dst,
|
bool ParseGET(const char* get, CPathName& src, CPathName& dst,
|
||||||
CPathName& bck, std::string& pin, std::string& ext) const;
|
CPathName& bck, gt_string pin, gt_string ext) const;
|
||||||
|
|
||||||
|
DWORD RunAsync(const char* strCmdLine) const;
|
||||||
|
DWORD RunSync(const char* strCmdLine) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CESignService(LPCTSTR pszServiceName, BOOL fCanStop = TRUE,
|
CESignService(LPCTSTR pszServiceName, BOOL fCanStop = TRUE,
|
||||||
|
@ -4,75 +4,123 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "PathName.h"
|
#include "PathName.h"
|
||||||
#include <strstream>
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// utility
|
// utility
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string& operator<<(std::string& str, int n)
|
char* wstring2string(const wchar_t* wstr)
|
||||||
{
|
{
|
||||||
std::strstream convert;
|
static char str[1024];
|
||||||
convert << n << '\0';
|
::WideCharToMultiByte(CP_ACP, WC_SEPCHARS, wstr, -1, str, sizeof(str), NULL, NULL);
|
||||||
str += convert.str();
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string& operator<<(std::string& str, char c)
|
wchar_t* string2wstring(const char* str)
|
||||||
{
|
{
|
||||||
const char s[2] = { c, '\0' };
|
static wchar_t wstr[1024];
|
||||||
str += s;
|
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, 1024);
|
||||||
return str;
|
return wstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// CPathName
|
// CPathName
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string CPathName::Path() const
|
static gt_string __tmp;
|
||||||
|
|
||||||
|
errno_t gt_strcpy(gt_string dst, const char* str)
|
||||||
{
|
{
|
||||||
char drive[_MAX_DRIVE], dir[_MAX_DIR];
|
assert(dst);
|
||||||
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), NULL, 0, NULL, 0);
|
errno_t e = 0;
|
||||||
std::string s = drive; s += dir;
|
if (str && *str)
|
||||||
return s;
|
e = ::strcpy_s(dst, sizeof(gt_string), str);
|
||||||
|
else
|
||||||
|
*dst = '\0';
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CPathName::FullName() const
|
errno_t gt_strcat(gt_string dst, const char* str)
|
||||||
|
{
|
||||||
|
assert(dst);
|
||||||
|
errno_t e = 0;
|
||||||
|
if (str && *str)
|
||||||
|
e = ::strcat_s(dst, sizeof(gt_string), str);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno_t gt_chrcat(gt_string dst, const char chr)
|
||||||
|
{
|
||||||
|
char s[2] = { chr, '\0' };
|
||||||
|
return gt_strcat(dst, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gt_strsame(const char* dst, const char* src)
|
||||||
|
{
|
||||||
|
return dst && src ? _stricmp(dst, src) == 0 : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CPathName::Path() const
|
||||||
|
{
|
||||||
|
char drive[_MAX_DRIVE], dir[_MAX_DIR];
|
||||||
|
_splitpath_s(_name, drive, sizeof(drive), dir, sizeof(dir), NULL, 0, NULL, 0);
|
||||||
|
gt_strcpy(__tmp, drive);
|
||||||
|
gt_strcat(__tmp, dir);
|
||||||
|
return __tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CPathName::FullName() const
|
||||||
{
|
{
|
||||||
char name[_MAX_FNAME], ext[_MAX_EXT];
|
char name[_MAX_FNAME], ext[_MAX_EXT];
|
||||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, name, sizeof(name), ext, sizeof(ext));
|
_splitpath_s(c_str(), NULL, 0, NULL, 0, name, sizeof(name), ext, sizeof(ext));
|
||||||
std::string s = name; s += ext;
|
gt_strcpy(__tmp, name);
|
||||||
return s;
|
gt_strcat(__tmp, ext);
|
||||||
|
return __tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CPathName::Name() const
|
const char* CPathName::Name() const
|
||||||
{
|
{
|
||||||
char name[_MAX_FNAME];
|
_splitpath_s(c_str(), NULL, 0, NULL, 0, __tmp, sizeof(__tmp), NULL, 0);
|
||||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, name, sizeof(name), NULL, 0);
|
return __tmp;
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
std::string CPathName::Ext() const
|
|
||||||
|
const char* CPathName::Ext() const
|
||||||
{
|
{
|
||||||
char ext[_MAX_EXT];
|
_splitpath_s(c_str(), NULL, 0, NULL, 0, NULL, 0, __tmp, sizeof(__tmp));
|
||||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, NULL, 0, ext, sizeof(ext));
|
return __tmp;
|
||||||
return ext;
|
}
|
||||||
|
|
||||||
|
CPathName& CPathName::Set(const char* p)
|
||||||
|
{
|
||||||
|
memset(_name, 0, sizeof(_name));
|
||||||
|
if (p && *p == '"')
|
||||||
|
{
|
||||||
|
gt_strcpy(_name, p+1);
|
||||||
|
_name[strlen(_name)-1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gt_strcpy(_name, p);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathName& CPathName::Set(const char* p, const char* n, const char* e)
|
CPathName& CPathName::Set(const char* p, const char* n, const char* e)
|
||||||
{
|
{
|
||||||
char path[_MAX_PATH];
|
memset(_name, 0, sizeof(_name));
|
||||||
_makepath_s(path, sizeof(path), NULL, p, n, e);
|
_makepath_s(_name, sizeof(_name), NULL, p, n, e);
|
||||||
return operator=(path);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathName& CPathName::SetPath(const char* p)
|
CPathName& CPathName::SetPath(const char* p)
|
||||||
{
|
{
|
||||||
char name[_MAX_FNAME], ext[_MAX_EXT], path[_MAX_PATH];
|
char name[_MAX_FNAME], ext[_MAX_EXT];
|
||||||
_splitpath_s(c_str(), NULL, NULL, NULL, NULL, name, sizeof(name), ext, sizeof(ext));
|
_splitpath_s(c_str(), NULL, NULL, NULL, NULL, name, sizeof(name), ext, sizeof(ext));
|
||||||
_makepath_s(path, sizeof(path), NULL, p, name, ext);
|
_makepath_s(_name, sizeof(_name), NULL, p, name, ext);
|
||||||
return operator=(path);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPathName& CPathName::SetName(const char* n)
|
CPathName& CPathName::SetName(const char* n)
|
||||||
@ -85,11 +133,10 @@ CPathName& CPathName::SetName(const char* n)
|
|||||||
|
|
||||||
CPathName& CPathName::SetExt(const char* e)
|
CPathName& CPathName::SetExt(const char* e)
|
||||||
{
|
{
|
||||||
char drive[_MAX_DRIVE], dir[_MAX_DIR], name[_MAX_FNAME];
|
char drive[_MAX_DRIVE], dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT];
|
||||||
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), name, sizeof(name), NULL, 0);
|
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), name, sizeof(name), ext, sizeof(ext));
|
||||||
char path[_MAX_PATH];
|
_makepath_s(_name, sizeof(_name), drive, dir, name, e);
|
||||||
_makepath_s(path, sizeof(path), drive, dir, name, e);
|
return *this;
|
||||||
return operator=(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPathName::IsFile() const
|
bool CPathName::IsFile() const
|
||||||
@ -108,15 +155,28 @@ bool CPathName::IsDirectory() const
|
|||||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
|
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CPathName::List(std::vector<CPathName>& files) const
|
size_t CPathName::Scan(CPathList* files) const
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATAA ffd;
|
WIN32_FIND_DATAA ffd = { 0 };
|
||||||
HANDLE hFind = ::FindFirstFileA(c_str(), &ffd);
|
|
||||||
|
PVOID pOldValue = NULL;
|
||||||
|
::Wow64DisableWow64FsRedirection(&pOldValue);
|
||||||
|
|
||||||
|
size_t nCount = 0;
|
||||||
|
|
||||||
|
CPathName tmp = c_str();
|
||||||
|
if (tmp.IsDirectory())
|
||||||
|
tmp.Set(c_str(), "*", "*");
|
||||||
|
|
||||||
|
HANDLE hFind = ::FindFirstFileA(tmp, &ffd);
|
||||||
while (hFind != INVALID_HANDLE_VALUE)
|
while (hFind != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
CPathName pn(ffd.cFileName);
|
if (files)
|
||||||
pn.SetPath(Path().c_str());
|
{
|
||||||
files.push_back(pn);
|
tmp.Set(Path(), ffd.cFileName, NULL);
|
||||||
|
files->push_back(tmp);
|
||||||
|
}
|
||||||
|
nCount++;
|
||||||
|
|
||||||
if (!::FindNextFileA(hFind, &ffd))
|
if (!::FindNextFileA(hFind, &ffd))
|
||||||
{
|
{
|
||||||
@ -124,7 +184,74 @@ size_t CPathName::List(std::vector<CPathName>& files) const
|
|||||||
hFind = INVALID_HANDLE_VALUE;
|
hFind = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return files.size();
|
|
||||||
|
::Wow64RevertWow64FsRedirection(pOldValue);
|
||||||
|
|
||||||
|
return nCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPathName::Copy(const CPathName& dst) const
|
||||||
|
{
|
||||||
|
return ::CopyFileA(c_str(), dst.c_str(), FALSE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPathName::Move(const CPathName& dst) const
|
||||||
|
{
|
||||||
|
if (dst.IsFile())
|
||||||
|
dst.Remove();
|
||||||
|
return ::MoveFileA(c_str(), dst.c_str()) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPathName::Remove() const
|
||||||
|
{
|
||||||
|
return ::DeleteFileA(c_str()) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// CPathList
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
size_t CPathList::push_back(const char* p)
|
||||||
|
{
|
||||||
|
CPathName& pn = operator[](size_t(-1));
|
||||||
|
pn = p;
|
||||||
|
return _items-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CPathList::push_back(const CPathName& p)
|
||||||
|
{
|
||||||
|
CPathName& pn = operator[](size_t(-1));
|
||||||
|
pn = p;
|
||||||
|
return _items-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CPathName& CPathList::operator[](size_t i) const
|
||||||
|
{
|
||||||
|
assert(i < _items);
|
||||||
|
return _file[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
CPathName& CPathList::operator[](size_t i)
|
||||||
|
{
|
||||||
|
if (i >= _items)
|
||||||
|
{
|
||||||
|
if (_items+1 >= _max)
|
||||||
|
{
|
||||||
|
const size_t s = _max ? _max*2 : 128;
|
||||||
|
CPathName* n = new CPathName[s];
|
||||||
|
for (size_t j = 0; j < _items; j++)
|
||||||
|
n[j].Set(_file[j]);
|
||||||
|
delete [] _file;
|
||||||
|
_file = n;
|
||||||
|
_max = s;
|
||||||
|
}
|
||||||
|
i = _items++;
|
||||||
|
}
|
||||||
|
return _file[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
CPathList::~CPathList()
|
||||||
|
{
|
||||||
|
if (_file)
|
||||||
|
delete [] _file;
|
||||||
|
}
|
@ -2,41 +2,77 @@
|
|||||||
#ifndef __PATHNAME_H__
|
#ifndef __PATHNAME_H__
|
||||||
#define __PATHNAME_H__
|
#define __PATHNAME_H__
|
||||||
|
|
||||||
#ifndef _STRING_
|
|
||||||
#include <string>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _VECTOR_
|
|
||||||
#include <vector>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// CPathName
|
// CPathName
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class CPathName : public std::string
|
typedef char gt_string[264];
|
||||||
|
errno_t gt_strcpy (_Out_z_cap_(264) gt_string dst, _In_z_ const char* src);
|
||||||
|
errno_t gt_strcat (_Out_z_cap_(264) gt_string dst, _In_z_ const char* src);
|
||||||
|
errno_t gt_chrcat (_Out_z_cap_(264) gt_string dst, _In_z_ const char src);
|
||||||
|
bool gt_strsame(_In_z_ const char* dst, _In_z_ const char* src);
|
||||||
|
|
||||||
|
class CPathList;
|
||||||
|
|
||||||
|
class CPathName
|
||||||
{
|
{
|
||||||
|
gt_string _name;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
size_t Scan(CPathList* list) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string Path() const;
|
bool empty() const { return *_name <= ' '; }
|
||||||
std::string FullName() const;
|
|
||||||
std::string Name() const;
|
|
||||||
std::string Ext() const;
|
|
||||||
|
|
||||||
|
const char* Path() const;
|
||||||
|
const char* FullName() const;
|
||||||
|
const char* Name() const;
|
||||||
|
const char* Ext() const;
|
||||||
|
|
||||||
|
CPathName& Set(const char* p);
|
||||||
CPathName& Set(const char* p, const char* n, const char* e);
|
CPathName& Set(const char* p, const char* n, const char* e);
|
||||||
CPathName& SetPath(const char* p);
|
CPathName& SetPath(const char* p);
|
||||||
CPathName& SetName(const char* n);
|
CPathName& SetName(const char* n);
|
||||||
CPathName& SetExt(const char* e);
|
CPathName& SetExt(const char* e);
|
||||||
|
|
||||||
|
const char* c_str() const { return _name; }
|
||||||
|
operator const char*() const { return c_str(); }
|
||||||
|
bool operator==(const char* str) const { return gt_strsame(_name, str); }
|
||||||
|
CPathName& operator=(const char* str) { return Set(str); }
|
||||||
|
CPathName& operator=(const CPathName& p) { return Set(p.c_str()); }
|
||||||
|
|
||||||
bool IsFile() const;
|
bool IsFile() const;
|
||||||
bool IsDirectory() const;
|
bool IsDirectory() const;
|
||||||
size_t List(std::vector<CPathName>& files) const;
|
|
||||||
|
size_t List(CPathList& files) const { return Scan(&files); }
|
||||||
|
size_t Count() const { return Scan(NULL); }
|
||||||
|
|
||||||
CPathName() {}
|
bool Copy(const CPathName& dst) const;
|
||||||
CPathName(const char* pathname) : std::string(pathname) {}
|
bool Move(const CPathName& dst) const;
|
||||||
|
bool Remove() const;
|
||||||
|
|
||||||
|
CPathName() { memset(_name, 0, sizeof(_name)); }
|
||||||
|
CPathName(const CPathName& n) { Set(n.c_str()); }
|
||||||
|
CPathName(const char* pathname) { Set(pathname); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string& operator<<(std::string& str, int n);
|
class CPathList
|
||||||
std::string& operator<<(std::string& str, char c);
|
{
|
||||||
|
size_t _items, _max;
|
||||||
|
CPathName* _file;
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t size() const { return _items; }
|
||||||
|
size_t push_back(const char* p);
|
||||||
|
size_t push_back(const CPathName& p);
|
||||||
|
const CPathName& operator[](size_t i) const;
|
||||||
|
CPathName& operator[](size_t i);
|
||||||
|
CPathList() : _items(0), _max(0), _file(NULL) {}
|
||||||
|
~CPathList();
|
||||||
|
};
|
||||||
|
|
||||||
|
char* wstring2string(const wchar_t* str);
|
||||||
|
wchar_t* string2wstring(const char* str);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -176,7 +176,7 @@ void CSSAservice::ServiceLoop(void)
|
|||||||
const int nSeconds = 5;
|
const int nSeconds = 5;
|
||||||
CheckDirectory();
|
CheckDirectory();
|
||||||
|
|
||||||
WIN32_FIND_DATA fd;
|
WIN32_FIND_DATA fd = { 0 };
|
||||||
HANDLE hf = ::FindFirstFile(TEXT("*.ssa"), &fd);
|
HANDLE hf = ::FindFirstFile(TEXT("*.ssa"), &fd);
|
||||||
if (hf)
|
if (hf)
|
||||||
{
|
{
|
||||||
|
@ -87,9 +87,9 @@ bool SCManager::Stop(LPCTSTR pszServiceName)
|
|||||||
::CloseServiceHandle(schService);
|
::CloseServiceHandle(schService);
|
||||||
|
|
||||||
if (bDone)
|
if (bDone)
|
||||||
wprintf(L"\n%s is stopped.\n", pszServiceName);
|
wprintf(L"%s stopped.\n", pszServiceName);
|
||||||
else
|
else
|
||||||
wprintf(L"\n%s failed to stop.\n", pszServiceName);
|
wprintf(L"%s failed to stop.\n", pszServiceName);
|
||||||
}
|
}
|
||||||
return bDone;
|
return bDone;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ bool SCManager::Start(LPCTSTR pszServiceName)
|
|||||||
bool bDone = false;
|
bool bDone = false;
|
||||||
if (IsOk())
|
if (IsOk())
|
||||||
{
|
{
|
||||||
SC_HANDLE schService = OpenService(_handle, pszServiceName, SERVICE_START);
|
SC_HANDLE schService = ::OpenService(_handle, pszServiceName, SERVICE_START);
|
||||||
if (schService)
|
if (schService)
|
||||||
{
|
{
|
||||||
bDone = ::StartService(schService, 0, NULL) != 0;
|
bDone = ::StartService(schService, 0, NULL) != 0;
|
||||||
@ -165,8 +165,9 @@ bool SCManager::Delete(LPCTSTR pszServiceName)
|
|||||||
// NOTE: If the function fails to install the service, it prints the error
|
// NOTE: If the function fails to install the service, it prints the error
|
||||||
// in the standard output stream for users to diagnose the problem.
|
// in the standard output stream for users to diagnose the problem.
|
||||||
//
|
//
|
||||||
void InstallService(LPCTSTR pszServiceName,
|
bool InstallService(LPCTSTR pszServiceName,
|
||||||
LPCTSTR pszDisplayName,
|
LPCTSTR pszDisplayName,
|
||||||
|
DWORD dwServiceType,
|
||||||
DWORD dwStartType,
|
DWORD dwStartType,
|
||||||
LPCTSTR pszDependencies,
|
LPCTSTR pszDependencies,
|
||||||
LPCTSTR pszAccount,
|
LPCTSTR pszAccount,
|
||||||
@ -174,10 +175,10 @@ void InstallService(LPCTSTR pszServiceName,
|
|||||||
{
|
{
|
||||||
TCHAR szPath[MAX_PATH];
|
TCHAR szPath[MAX_PATH];
|
||||||
if (::GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
|
if (::GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
|
||||||
{
|
return LogError("GetModuleFileName");
|
||||||
LogError("GetModuleFileName");
|
|
||||||
return;
|
if (dwServiceType == 0)
|
||||||
}
|
dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||||
|
|
||||||
// Open the local default service control manager database
|
// Open the local default service control manager database
|
||||||
SCManager schSCManager(SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
|
SCManager schSCManager(SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
|
||||||
@ -189,7 +190,7 @@ void InstallService(LPCTSTR pszServiceName,
|
|||||||
pszServiceName, // Name of service
|
pszServiceName, // Name of service
|
||||||
pszDisplayName, // Name to display
|
pszDisplayName, // Name to display
|
||||||
SERVICE_QUERY_STATUS, // Desired access
|
SERVICE_QUERY_STATUS, // Desired access
|
||||||
SERVICE_WIN32_OWN_PROCESS, // Service type
|
dwServiceType, // Service type
|
||||||
dwStartType, // Service start type
|
dwStartType, // Service start type
|
||||||
SERVICE_ERROR_NORMAL, // Error control type
|
SERVICE_ERROR_NORMAL, // Error control type
|
||||||
szPath, // Service's binary
|
szPath, // Service's binary
|
||||||
@ -201,12 +202,13 @@ void InstallService(LPCTSTR pszServiceName,
|
|||||||
);
|
);
|
||||||
if (schService != NULL)
|
if (schService != NULL)
|
||||||
{
|
{
|
||||||
wprintf(L"%s has been installed.\n", pszServiceName);
|
wprintf(L"%s (%s) has been installed.\n", pszServiceName, pszDisplayName);
|
||||||
CloseServiceHandle(schService);
|
CloseServiceHandle(schService);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogError("CreateService");
|
return LogError("CreateService");
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,27 +224,33 @@ void InstallService(LPCTSTR pszServiceName,
|
|||||||
// NOTE: If the function fails to uninstall the service, it prints the
|
// NOTE: If the function fails to uninstall the service, it prints the
|
||||||
// error in the standard output stream for users to diagnose the problem.
|
// error in the standard output stream for users to diagnose the problem.
|
||||||
//
|
//
|
||||||
void UninstallService(PWSTR pszServiceName)
|
bool UninstallService(PWSTR pszServiceName)
|
||||||
{
|
{
|
||||||
|
bool done = false;
|
||||||
// Open the local default service control manager database
|
// Open the local default service control manager database
|
||||||
SCManager schSCManager(SC_MANAGER_CONNECT);
|
SCManager schSCManager(SC_MANAGER_CONNECT);
|
||||||
if (schSCManager.IsOk())
|
if (schSCManager.IsOk())
|
||||||
{
|
{
|
||||||
schSCManager.Stop(pszServiceName);
|
schSCManager.Stop(pszServiceName);
|
||||||
schSCManager.Delete(pszServiceName);
|
done = schSCManager.Delete(pszServiceName);
|
||||||
}
|
}
|
||||||
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartService(PWSTR pszServiceName)
|
bool StartService(PWSTR pszServiceName)
|
||||||
{
|
{
|
||||||
|
bool done = false;
|
||||||
SCManager schSCManager(SC_MANAGER_CONNECT);
|
SCManager schSCManager(SC_MANAGER_CONNECT);
|
||||||
if (schSCManager.IsOk())
|
if (schSCManager.IsOk())
|
||||||
schSCManager.Start(pszServiceName);
|
done = schSCManager.Start(pszServiceName);
|
||||||
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopService(PWSTR pszServiceName)
|
bool StopService(PWSTR pszServiceName)
|
||||||
{
|
{
|
||||||
|
bool done = false;
|
||||||
SCManager schSCManager(SC_MANAGER_CONNECT);
|
SCManager schSCManager(SC_MANAGER_CONNECT);
|
||||||
if (schSCManager.IsOk())
|
if (schSCManager.IsOk())
|
||||||
schSCManager.Stop(pszServiceName);
|
done = schSCManager.Stop(pszServiceName);
|
||||||
|
return done;
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,9 @@
|
|||||||
// NOTE: If the function fails to install the service, it prints the error
|
// NOTE: If the function fails to install the service, it prints the error
|
||||||
// in the standard output stream for users to diagnose the problem.
|
// in the standard output stream for users to diagnose the problem.
|
||||||
//
|
//
|
||||||
void InstallService(LPCTSTR pszServiceName,
|
bool InstallService(LPCTSTR pszServiceName,
|
||||||
LPCTSTR pszDisplayName,
|
LPCTSTR pszDisplayName,
|
||||||
|
DWORD dwServiceType,
|
||||||
DWORD dwStartType,
|
DWORD dwStartType,
|
||||||
LPCTSTR pszDependencies,
|
LPCTSTR pszDependencies,
|
||||||
LPCTSTR pszAccount,
|
LPCTSTR pszAccount,
|
||||||
@ -58,7 +59,7 @@ void InstallService(LPCTSTR pszServiceName,
|
|||||||
// NOTE: If the function fails to uninstall the service, it prints the
|
// NOTE: If the function fails to uninstall the service, it prints the
|
||||||
// error in the standard output stream for users to diagnose the problem.
|
// error in the standard output stream for users to diagnose the problem.
|
||||||
//
|
//
|
||||||
void UninstallService(PWSTR pszServiceName);
|
bool UninstallService(PWSTR pszServiceName);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -73,5 +74,5 @@ void UninstallService(PWSTR pszServiceName);
|
|||||||
// NOTE: If the function fails to uninstall the service, it prints the
|
// NOTE: If the function fails to uninstall the service, it prints the
|
||||||
// error in the standard output stream for users to diagnose the problem.
|
// error in the standard output stream for users to diagnose the problem.
|
||||||
//
|
//
|
||||||
void StartService(PWSTR pszServiceName);
|
bool StartService(PWSTR pszServiceName);
|
||||||
void StopService(PWSTR pszServiceName);
|
bool StopService(PWSTR pszServiceName);
|
||||||
|
@ -45,7 +45,7 @@ bool gestione_sheet(TSheet_field& s, int r, KEY k)
|
|||||||
{
|
{
|
||||||
TRelation *rel = app().get_relation();
|
TRelation *rel = app().get_relation();
|
||||||
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
|
TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
|
||||||
TMask &msk = s.sheet_mask();
|
TMask& msk = s.sheet_mask();
|
||||||
|
|
||||||
// A questo punto devo modificare il contenuto di CARADD:
|
// A questo punto devo modificare il contenuto di CARADD:
|
||||||
// ricavo il suo contenuto da maschera, e lo scrivo nella cache
|
// ricavo il suo contenuto da maschera, e lo scrivo nella cache
|
||||||
|
@ -14,7 +14,7 @@ class TGestione_tree: public TRelation_application
|
|||||||
protected:
|
protected:
|
||||||
virtual bool user_create();
|
virtual bool user_create();
|
||||||
virtual bool user_destroy();
|
virtual bool user_destroy();
|
||||||
virtual bool changing_mask(int mode) {return FALSE;}
|
virtual bool changing_mask(int mode) {return false;}
|
||||||
|
|
||||||
// void gestione_analisi();
|
// void gestione_analisi();
|
||||||
// void gestione_saldi();
|
// void gestione_saldi();
|
||||||
@ -22,13 +22,6 @@ class TGestione_tree: public TRelation_application
|
|||||||
public:
|
public:
|
||||||
virtual TMask* get_mask(int mode) {return _msk;}
|
virtual TMask* get_mask(int mode) {return _msk;}
|
||||||
virtual TRelation* get_relation() const {return _anas;}
|
virtual TRelation* get_relation() const {return _anas;}
|
||||||
|
|
||||||
TGestione_tree()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
virtual ~TGestione_tree()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool gestione_sheet(TSheet_field& s, int r, KEY k);
|
bool gestione_sheet(TSheet_field& s, int r, KEY k);
|
||||||
|
@ -1095,11 +1095,9 @@ TMask* TGestione_preventivo_app::get_mask( int mode )
|
|||||||
TGestione_preventivo_msk* m = new TGestione_preventivo_msk(tipodoc);
|
TGestione_preventivo_msk* m = new TGestione_preventivo_msk(tipodoc);
|
||||||
_doc_masks.add(tipodoc, m);
|
_doc_masks.add(tipodoc, m);
|
||||||
const TTipo_documento& tdoc = m->doc().tipo();
|
const TTipo_documento& tdoc = m->doc().tipo();
|
||||||
const TString_array& handlers = tdoc.handlers();
|
const TPointer_array& handlers = tdoc.handlers();
|
||||||
FOR_EACH_ARRAY_ROW(handlers, i, row)
|
FOR_EACH_ARRAY_ITEM(handlers, i, obj)
|
||||||
{
|
m->user_set_handler( i, handlers.get_long(i) );
|
||||||
m->user_set_handler( row->get_int( 0 ), row->get_int( 1 ) );
|
|
||||||
}
|
|
||||||
TSheet_field & sh = m->sfield(F_SHEET);
|
TSheet_field & sh = m->sfield(F_SHEET);
|
||||||
const int y = m->sh_y() - 1;
|
const int y = m->sh_y() - 1;
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
res/Balls/ok.png
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
res/campo.ico
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 15 KiB |
@ -233,7 +233,7 @@ Item_01_03 = 7013,Cerca...\tF7,
|
|||||||
Item_01_04 = 7014,Cerca il prossimo\tF8,D
|
Item_01_04 = 7014,Cerca il prossimo\tF8,D
|
||||||
|
|
||||||
[Menu_8000]
|
[Menu_8000]
|
||||||
Item_00 = 10001,~Proprieta'
|
Item_00 = 10001,~Proprietŕ
|
||||||
Item_00_00 = 8001,&Salva impostazioni colonne
|
Item_00_00 = 8001,&Salva impostazioni colonne
|
||||||
Item_00_01 = 8002,&Ripristina impostazioni colonne
|
Item_00_01 = 8002,&Ripristina impostazioni colonne
|
||||||
Item_00_02 = 8004,Esportazione in E&xcel
|
Item_00_02 = 8004,Esportazione in E&xcel
|
||||||
@ -248,6 +248,7 @@ Item_00_02 = 30007,Cambio &utente...
|
|||||||
Item_00_03 = -1,Separator
|
Item_00_03 = -1,Separator
|
||||||
Item_00_04 = 30002,&Aspetto
|
Item_00_04 = 30002,&Aspetto
|
||||||
Item_00_05 = 30003,&Editors
|
Item_00_05 = 30003,&Editors
|
||||||
|
Item_00_06 = 30008,&Mail...
|
||||||
Item_01 = 32350,&Preferiti
|
Item_01 = 32350,&Preferiti
|
||||||
Item_01_00 = 30005,&Aggiungi
|
Item_01_00 = 30005,&Aggiungi
|
||||||
Item_01_01 = 30006,&Organizza
|
Item_01_01 = 30006,&Organizza
|
||||||
|
23
ve/vetbrpd.h
@ -1,21 +1,2 @@
|
|||||||
|
#define F_CODICE 101
|
||||||
|
#define F_DESCR 102
|
||||||
// campi maschera batbrpd.msk
|
|
||||||
|
|
||||||
#define F_CODICE 101
|
|
||||||
#define F_DESCR 102
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|