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
|
||||
#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.
|
||||
#define SERVICE_START_TYPE SERVICE_AUTO_START
|
||||
|
||||
@ -38,7 +41,8 @@
|
||||
#define SERVICE_DEPENDENCIES TEXT("")
|
||||
|
||||
// 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
|
||||
#define SERVICE_PASSWORD NULL
|
||||
@ -65,16 +69,18 @@ int wmain(int argc, wchar_t *argv[])
|
||||
{
|
||||
if (_wcsicmp(L"install", argv[1] + 1) == 0)
|
||||
{
|
||||
InstallService(
|
||||
if (InstallService(
|
||||
SERVICE_NAME, // Name of service
|
||||
SERVICE_DISPLAY_NAME, // Name to display
|
||||
SERVICE_TYPE, // Service type
|
||||
SERVICE_START_TYPE, // Service start type
|
||||
SERVICE_DEPENDENCIES, // Dependencies
|
||||
SERVICE_ACCOUNT, // Service running 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);
|
||||
}
|
||||
@ -98,8 +104,9 @@ int wmain(int argc, wchar_t *argv[])
|
||||
CESignService service(SERVICE_NAME);
|
||||
if (!CServiceBase::Run(service))
|
||||
{
|
||||
wprintf(L"Parameters: -install -start -stop -restart -remove\n");
|
||||
wprintf(L"Running as standard process from command line\n");
|
||||
printf("ESignService 1.4 %s\n", __TIMESTAMP__);
|
||||
printf("Parameters: -install -start -stop -restart -remove\n");
|
||||
printf("Running as standard process from command line\n");
|
||||
service.ServiceLoop();
|
||||
}
|
||||
}
|
||||
|
@ -2,341 +2,33 @@
|
||||
#include "ESignService.h"
|
||||
#include "ThreadPool.h"
|
||||
|
||||
#include "esigner.h"
|
||||
#include "PathName.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
#include <zmq.h>
|
||||
|
||||
#include <Wtsapi32.h>
|
||||
#pragma comment(lib, "Wtsapi32.lib")
|
||||
|
||||
#pragma endregion
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 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(val), "./esigner.ini");
|
||||
return val;
|
||||
::GetPrivateProfileStringA("Default", key, "", val, sizeof(gt_string), "./esigner.ini");
|
||||
return *val ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
static int GetIniInteger(const char* key)
|
||||
{
|
||||
char val[_MAX_PATH];
|
||||
::GetPrivateProfileStringA("Default", key, "", val, sizeof(val), "./esigner.ini");
|
||||
gt_string val = { 0 };
|
||||
GetIniString(key, 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
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -405,35 +97,48 @@ char CESignService::ParseHex(const char* hex) const
|
||||
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;
|
||||
int i = 0;
|
||||
for (; *s != '&' && *s > ' '; s++)
|
||||
{
|
||||
if (*s == '%')
|
||||
{
|
||||
const char h = ParseHex(s+1);
|
||||
str += h;
|
||||
gt_chrcat(str, h);
|
||||
s += 2;
|
||||
}
|
||||
else
|
||||
str += *s;
|
||||
gt_chrcat(str, *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,
|
||||
std::string& pin, std::string& ext) const
|
||||
gt_string pin, gt_string ext) const
|
||||
{
|
||||
src = dst = bck = "";
|
||||
pin = "";
|
||||
ext = "";
|
||||
gt_strcpy(pin, "");
|
||||
gt_strcpy(ext, "");
|
||||
while (get != NULL)
|
||||
{
|
||||
const char* equal = strchr(get, '=');
|
||||
if (equal != NULL)
|
||||
{
|
||||
if (*(equal-1) > 'Z')
|
||||
break;
|
||||
|
||||
switch (*(equal-3))
|
||||
{
|
||||
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 'P': get = ParseString(equal+1, pin); break; // PIN
|
||||
case 'S': get = ParseString(equal+1, src); break; // SRC
|
||||
default : break;
|
||||
default : get = equal+1; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -450,6 +155,107 @@ bool CESignService::ParseGET(const char* get, CPathName& src, CPathName& dst, CP
|
||||
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)
|
||||
//
|
||||
@ -476,8 +282,9 @@ void CESignService::ServiceLoop(void)
|
||||
/* Data structure to hold the ZMQ_STREAM ID */
|
||||
uint8_t id [256];
|
||||
/* 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];
|
||||
|
||||
while (!m_fStopping)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
CPathName src, dst, bck;
|
||||
std::string pin, ext;
|
||||
gt_string pin = { 0 }, ext = { 0 };
|
||||
ParseGET(raw, src, dst, bck, pin, ext);
|
||||
|
||||
/* Sends the ID frame followed by the response */
|
||||
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 */
|
||||
std::string log = "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
||||
CEsigner esigner;
|
||||
esigner.SetOutputString(log);
|
||||
esigner.Sign(src, dst, bck, pin, ext);
|
||||
zmq_send (socket, log.c_str(),log.length(), ZMQ_SNDMORE);
|
||||
CPathName pdf; pdf.Set(src, "*", "pdf");
|
||||
const int nTotal = pdf.Count();
|
||||
|
||||
if (nTotal > 0)
|
||||
{
|
||||
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 */
|
||||
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
|
||||
// main service function (ServiceWorkerThread).
|
||||
m_fStopping = TRUE;
|
||||
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||
throw GetLastError();
|
||||
if (::WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||
throw ::GetLastError();
|
||||
}
|
||||
|
@ -33,9 +33,13 @@ protected:
|
||||
virtual void OnStop();
|
||||
|
||||
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,
|
||||
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:
|
||||
CESignService(LPCTSTR pszServiceName, BOOL fCanStop = TRUE,
|
||||
|
@ -4,75 +4,123 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "PathName.h"
|
||||
#include <strstream>
|
||||
#pragma endregion
|
||||
|
||||
#include <cassert>
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma endregion
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// utility
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
std::string& operator<<(std::string& str, int n)
|
||||
char* wstring2string(const wchar_t* wstr)
|
||||
{
|
||||
std::strstream convert;
|
||||
convert << n << '\0';
|
||||
str += convert.str();
|
||||
static char str[1024];
|
||||
::WideCharToMultiByte(CP_ACP, WC_SEPCHARS, wstr, -1, str, sizeof(str), NULL, NULL);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string& operator<<(std::string& str, char c)
|
||||
wchar_t* string2wstring(const char* str)
|
||||
{
|
||||
const char s[2] = { c, '\0' };
|
||||
str += s;
|
||||
return str;
|
||||
static wchar_t wstr[1024];
|
||||
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, 1024);
|
||||
return wstr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 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];
|
||||
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), NULL, 0, NULL, 0);
|
||||
std::string s = drive; s += dir;
|
||||
return s;
|
||||
assert(dst);
|
||||
errno_t e = 0;
|
||||
if (str && *str)
|
||||
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];
|
||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, name, sizeof(name), ext, sizeof(ext));
|
||||
std::string s = name; s += ext;
|
||||
return s;
|
||||
gt_strcpy(__tmp, name);
|
||||
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, name, sizeof(name), NULL, 0);
|
||||
return name;
|
||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, __tmp, sizeof(__tmp), NULL, 0);
|
||||
return __tmp;
|
||||
}
|
||||
std::string CPathName::Ext() const
|
||||
|
||||
const char* CPathName::Ext() const
|
||||
{
|
||||
char ext[_MAX_EXT];
|
||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, NULL, 0, ext, sizeof(ext));
|
||||
return ext;
|
||||
_splitpath_s(c_str(), NULL, 0, NULL, 0, NULL, 0, __tmp, sizeof(__tmp));
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
char path[_MAX_PATH];
|
||||
_makepath_s(path, sizeof(path), NULL, p, n, e);
|
||||
return operator=(path);
|
||||
memset(_name, 0, sizeof(_name));
|
||||
_makepath_s(_name, sizeof(_name), NULL, p, n, e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
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));
|
||||
_makepath_s(path, sizeof(path), NULL, p, name, ext);
|
||||
return operator=(path);
|
||||
_makepath_s(_name, sizeof(_name), NULL, p, name, ext);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPathName& CPathName::SetName(const char* n)
|
||||
@ -85,11 +133,10 @@ CPathName& CPathName::SetName(const char* n)
|
||||
|
||||
CPathName& CPathName::SetExt(const char* e)
|
||||
{
|
||||
char drive[_MAX_DRIVE], dir[_MAX_DIR], name[_MAX_FNAME];
|
||||
_splitpath_s(c_str(), drive, sizeof(drive), dir, sizeof(dir), name, sizeof(name), NULL, 0);
|
||||
char path[_MAX_PATH];
|
||||
_makepath_s(path, sizeof(path), drive, dir, name, e);
|
||||
return operator=(path);
|
||||
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), ext, sizeof(ext));
|
||||
_makepath_s(_name, sizeof(_name), drive, dir, name, e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CPathName::IsFile() const
|
||||
@ -108,15 +155,28 @@ bool CPathName::IsDirectory() const
|
||||
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;
|
||||
HANDLE hFind = ::FindFirstFileA(c_str(), &ffd);
|
||||
WIN32_FIND_DATAA ffd = { 0 };
|
||||
|
||||
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)
|
||||
{
|
||||
CPathName pn(ffd.cFileName);
|
||||
pn.SetPath(Path().c_str());
|
||||
files.push_back(pn);
|
||||
if (files)
|
||||
{
|
||||
tmp.Set(Path(), ffd.cFileName, NULL);
|
||||
files->push_back(tmp);
|
||||
}
|
||||
nCount++;
|
||||
|
||||
if (!::FindNextFileA(hFind, &ffd))
|
||||
{
|
||||
@ -124,7 +184,74 @@ size_t CPathName::List(std::vector<CPathName>& files) const
|
||||
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__
|
||||
#define __PATHNAME_H__
|
||||
|
||||
#ifndef _STRING_
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#ifndef _VECTOR_
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 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:
|
||||
size_t Scan(CPathList* list) const;
|
||||
|
||||
public:
|
||||
std::string Path() const;
|
||||
std::string FullName() const;
|
||||
std::string Name() const;
|
||||
std::string Ext() const;
|
||||
bool empty() const { return *_name <= ' '; }
|
||||
|
||||
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& SetPath(const char* p);
|
||||
CPathName& SetName(const char* n);
|
||||
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 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() {}
|
||||
CPathName(const char* pathname) : std::string(pathname) {}
|
||||
bool Copy(const CPathName& dst) const;
|
||||
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);
|
||||
std::string& operator<<(std::string& str, char c);
|
||||
class CPathList
|
||||
{
|
||||
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
|
||||
|
@ -176,7 +176,7 @@ void CSSAservice::ServiceLoop(void)
|
||||
const int nSeconds = 5;
|
||||
CheckDirectory();
|
||||
|
||||
WIN32_FIND_DATA fd;
|
||||
WIN32_FIND_DATA fd = { 0 };
|
||||
HANDLE hf = ::FindFirstFile(TEXT("*.ssa"), &fd);
|
||||
if (hf)
|
||||
{
|
||||
|
@ -87,9 +87,9 @@ bool SCManager::Stop(LPCTSTR pszServiceName)
|
||||
::CloseServiceHandle(schService);
|
||||
|
||||
if (bDone)
|
||||
wprintf(L"\n%s is stopped.\n", pszServiceName);
|
||||
wprintf(L"%s stopped.\n", pszServiceName);
|
||||
else
|
||||
wprintf(L"\n%s failed to stop.\n", pszServiceName);
|
||||
wprintf(L"%s failed to stop.\n", pszServiceName);
|
||||
}
|
||||
return bDone;
|
||||
}
|
||||
@ -99,7 +99,7 @@ bool SCManager::Start(LPCTSTR pszServiceName)
|
||||
bool bDone = false;
|
||||
if (IsOk())
|
||||
{
|
||||
SC_HANDLE schService = OpenService(_handle, pszServiceName, SERVICE_START);
|
||||
SC_HANDLE schService = ::OpenService(_handle, pszServiceName, SERVICE_START);
|
||||
if (schService)
|
||||
{
|
||||
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
|
||||
// in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void InstallService(LPCTSTR pszServiceName,
|
||||
bool InstallService(LPCTSTR pszServiceName,
|
||||
LPCTSTR pszDisplayName,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwStartType,
|
||||
LPCTSTR pszDependencies,
|
||||
LPCTSTR pszAccount,
|
||||
@ -174,10 +175,10 @@ void InstallService(LPCTSTR pszServiceName,
|
||||
{
|
||||
TCHAR szPath[MAX_PATH];
|
||||
if (::GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
|
||||
{
|
||||
LogError("GetModuleFileName");
|
||||
return;
|
||||
}
|
||||
return LogError("GetModuleFileName");
|
||||
|
||||
if (dwServiceType == 0)
|
||||
dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||
|
||||
// Open the local default service control manager database
|
||||
SCManager schSCManager(SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
|
||||
@ -189,7 +190,7 @@ void InstallService(LPCTSTR pszServiceName,
|
||||
pszServiceName, // Name of service
|
||||
pszDisplayName, // Name to display
|
||||
SERVICE_QUERY_STATUS, // Desired access
|
||||
SERVICE_WIN32_OWN_PROCESS, // Service type
|
||||
dwServiceType, // Service type
|
||||
dwStartType, // Service start type
|
||||
SERVICE_ERROR_NORMAL, // Error control type
|
||||
szPath, // Service's binary
|
||||
@ -201,12 +202,13 @@ void InstallService(LPCTSTR pszServiceName,
|
||||
);
|
||||
if (schService != NULL)
|
||||
{
|
||||
wprintf(L"%s has been installed.\n", pszServiceName);
|
||||
wprintf(L"%s (%s) has been installed.\n", pszServiceName, pszDisplayName);
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
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
|
||||
// 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
|
||||
SCManager schSCManager(SC_MANAGER_CONNECT);
|
||||
if (schSCManager.IsOk())
|
||||
{
|
||||
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);
|
||||
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);
|
||||
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
|
||||
// in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void InstallService(LPCTSTR pszServiceName,
|
||||
bool InstallService(LPCTSTR pszServiceName,
|
||||
LPCTSTR pszDisplayName,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwStartType,
|
||||
LPCTSTR pszDependencies,
|
||||
LPCTSTR pszAccount,
|
||||
@ -58,7 +59,7 @@ void InstallService(LPCTSTR pszServiceName,
|
||||
// NOTE: If the function fails to uninstall the service, it prints the
|
||||
// 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
|
||||
// error in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void StartService(PWSTR pszServiceName);
|
||||
void StopService(PWSTR pszServiceName);
|
||||
bool StartService(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();
|
||||
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:
|
||||
// ricavo il suo contenuto da maschera, e lo scrivo nella cache
|
||||
|
@ -14,7 +14,7 @@ class TGestione_tree: public TRelation_application
|
||||
protected:
|
||||
virtual bool user_create();
|
||||
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_saldi();
|
||||
@ -22,13 +22,6 @@ class TGestione_tree: public TRelation_application
|
||||
public:
|
||||
virtual TMask* get_mask(int mode) {return _msk;}
|
||||
virtual TRelation* get_relation() const {return _anas;}
|
||||
|
||||
TGestione_tree()
|
||||
{
|
||||
}
|
||||
virtual ~TGestione_tree()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
_doc_masks.add(tipodoc, m);
|
||||
const TTipo_documento& tdoc = m->doc().tipo();
|
||||
const TString_array& handlers = tdoc.handlers();
|
||||
FOR_EACH_ARRAY_ROW(handlers, i, row)
|
||||
{
|
||||
m->user_set_handler( row->get_int( 0 ), row->get_int( 1 ) );
|
||||
}
|
||||
const TPointer_array& handlers = tdoc.handlers();
|
||||
FOR_EACH_ARRAY_ITEM(handlers, i, obj)
|
||||
m->user_set_handler( i, handlers.get_long(i) );
|
||||
TSheet_field & sh = m->sfield(F_SHEET);
|
||||
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
|
||||
|
||||
[Menu_8000]
|
||||
Item_00 = 10001,~Proprieta'
|
||||
Item_00 = 10001,~Proprietŕ
|
||||
Item_00_00 = 8001,&Salva impostazioni colonne
|
||||
Item_00_01 = 8002,&Ripristina impostazioni colonne
|
||||
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_04 = 30002,&Aspetto
|
||||
Item_00_05 = 30003,&Editors
|
||||
Item_00_06 = 30008,&Mail...
|
||||
Item_01 = 32350,&Preferiti
|
||||
Item_01_00 = 30005,&Aggiungi
|
||||
Item_01_01 = 30006,&Organizza
|
||||
|
23
ve/vetbrpd.h
@ -1,21 +1,2 @@
|
||||
|
||||
|
||||
// campi maschera batbrpd.msk
|
||||
|
||||
#define F_CODICE 101
|
||||
#define F_DESCR 102
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define F_CODICE 101
|
||||
#define F_DESCR 102
|
||||
|