Versione 12

git-svn-id: svn://10.65.10.50/branches/R_10_00@23098 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2015-05-15 09:09:10 +00:00
parent 61bd326fe7
commit d40707a134
46 changed files with 467 additions and 463 deletions

View File

@ -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();
}
}

View File

@ -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, &currentToken);
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();
}

View File

@ -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,

View File

@ -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;
}

View 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

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -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

View File

@ -1,21 +1,2 @@
// campi maschera batbrpd.msk
#define F_CODICE 101
#define F_DESCR 102
#define F_CODICE 101
#define F_DESCR 102