📄 notlstnr.cpp
字号:
APIEXPORT DWORD S4N_Write(
DWORD dwData,
LPVOID pInBuf,
DWORD dwInLen
) {
DebugPrint(TEXT("Write - dwData: %lx\n"), dwData);
return 0;
}
/**
* Service callback: not implemented.
*/
APIEXPORT DWORD S4N_Seek(
DWORD dwData,
long pos,
DWORD type
) {
DebugPrint(TEXT("Seek - dwData: %lx\n"), dwData);
return 0;
}
///////////////////////////////////////////////////////////////////
// Notification Listener: connection handler
///////////////////////////////////////////////////////////////////
/**
* Open the socket connection and waits for the server messages.
*/
static DWORD acceptConnection(SOCKET sock)
{
if (g_dwServiceState != SERVICE_STATE_ON) {
// Do not accept connections unless the service is on
// ALWAYS close the socket, even if you return
// FALSE. Services.exe leaves it to the
// service to close the socket in all cases.
DebugPrint(L"S4ND: ERROR: Service Conn fails."
L"Service State != ON. State = <%d>\r\n",
g_dwServiceState);
send(sock, RESP_BUSY, strlen(RESP_BUSY),0);
closesocket(sock);
return ERROR_SERVICE_NOT_ACTIVE;
}
int ret = ERROR_EXCEPTION_IN_SERVICE;
__try {
DebugPrint(L"Starting worker...\n");
ret = startWorker(sock);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
DebugPrint(L"Exception in Worker thread.\n\n");
}
if( ret != ERROR_SUCCESS ) {
if (ret == ERROR_BUSY ){
DebugPrint(L"Worker busy...\n\r");
send(sock, RESP_BUSY, strlen(RESP_BUSY),0);
}
else {
DebugPrint(L"Worker error...\n\r");
send(sock, RESP_GENERIC, strlen(RESP_BUSY),0);
}
closesocket(sock);
}
// Worker thread will close the socket.
return ret;
}
///////////////////////////////////////////////////////////////////
// Address change handler
///////////////////////////////////////////////////////////////////
// FIXME: use the DM
/*
* Test a configuration property to understand if the client has already
* notified the server.
*/
static bool isServerNotified()
{
wchar_t buf[10];
memset(buf, 0, 10*sizeof(wchar_t));
getClientConfigurationInternal (TEXT(""), PROPERTY_SPDM_SERVER_NOTIFIED,
buf, FALSE);
return ( wcscmp(buf, TEXT("1")) == 0);
}
// FIXME: use the DM
/*
* Set a configuration property to mark the client has
* notified the server.
*/
void setServerNotified(bool val)
{
setClientConfiguration(
TEXT(""),
PROPERTY_SPDM_SERVER_NOTIFIED,
( (val) ? TEXT("1") : TEXT("0") ),
NULL);
}
/*
* Start a particular sync saying to the server the new client IP address.
* It sets the server notified parameter if succesfully finished.
*/
DWORD addressChangeHandler(void)
{
static wchar_t oldIP[40] = TEXT("127.0.0.1");
wchar_t newIP[40];
DWORD ret = ERROR_SUCCESS;
bool useSTP = false;
bool useCTP = false;
//MessageBox (NULL, TEXT("addressChangeHandler"), TEXT("Test"), MB_SETFOREGROUND | MB_OK);
// Read getPush -> switch if using STP / CTP
int pushType = getPushTypeFromRegistry();
if (pushType & 1) {
useSTP = true;
}
if (pushType & 2) {
useCTP = true;
}
if (!useSTP && !useCTP) {
// Nothing to do
setServerNotified(false);
return 0;
}
LOG.debug("useSTP = %d, useCTP = %d", useSTP, useCTP);
if (checkNetwork()) {
getIPAddress(newIP);
if (wcscmp(newIP, TEXT("192.168.55.101"))==0 ||
wcsstr(newIP, TEXT("169.254.2.")) ) {
DebugPrint(L"Device is using ActiveSync -> use only CTP\n");
wcscpy(oldIP, newIP);
setServerNotified(false);
useSTP = false;
useCTP = true;
}
// The server is already notified and the IP is
// the same of the current, do not send a new notification.
if ( isServerNotified() && (wcscmp(oldIP, newIP)==0) ) {
DebugPrint(TEXT("Server already notified.\n"));
return ret;
}
// Save the IP
wcscpy(oldIP, newIP);
DebugPrint(L"New IP: %s\n", newIP);
HANDLE stpThread = NULL;
CTPManager* ctpManager = CTPManager::getInstance();
// ----------- STP -----------
if (useSTP) {
// create STP thread, get handle of stpThread
stpThread = CreateThread(NULL, 0, stpWorker, NULL, 0, NULL);
if (!stpThread) {
LOG.error("Error creating STP thread: code 0x%08x", GetLastError());
}
}
// ----------- CTP -----------
if (useCTP) {
// create CTP thread, passing handle stpThread (NULL if not created)
ctpManager->startCTP(stpThread);
}
}
else { // end server notification
setServerNotified(false);
}
LOG.debug("Exiting addressChangeHandler");
return ret;
}
int getPushTypeFromRegistry() {
CTPConfig config(APPLICATION_URI);
config.readCTPConfig();
return config.getPush();
}
char* extractNonceParam(CTPMessage* authStatusMsg) {
if (authStatusMsg->params.size() == 0) {
// Expected NONCE param is missing -> restore connection
//LOG.debug("Error receiving Status message: NONCE param is missing");
return NULL;
}
list<CTPParam>::iterator param = authStatusMsg->params.begin();
if ((*param).getParamCode() == P_NONCE) {
int nonceLen = (*param).getValueLength();
void* nonce = (*param).getValue();
// Return buffer is new allocated!
return stringdup((char*)nonce, nonceLen);
}
else {
// Unexpected Status param -> restore connection
//LOG.debug("Error receiving Status message: unexpected param '0x%02x'", (*param).getParamCode());
return NULL;
}
}
/**
* Starts the program "startsync.exe" (or syncmail.exe) with params:
* "manual <sourcename1, sourcename2,...>" where sourcenames are
* retrieved from the SyncNotification passed.
* @note the process is started and then the control is returned
* immediately to the caller (no wait on the process started)
* @param sn pointer to the SyncNotification object to read
* @return the PID of process started, a value < 0 in case of errors
*/
int startSyncFromSAN(SyncNotification* sn) {
if (!sn) {
LOG.error("CTP notification error: SyncNotification is NULL");
return -1;
}
// Get number of sources to sync
int n = sn->getNumSyncs();
if (!n) {
LOG.info("CTP notification error: no sources to sync from server");
return -2;
}
//
// Call "startsync.exe" with command-line parameters (sequence of source names)
//
wstring app = L"startsync.exe";
wstring cmdLine = L"manual";
int count = 0;
for (int i=0; i<n; i++) {
SyncAlert* sync = sn->getSyncAlert(i);
if(!sync) {
LOG.error("CTP notification error: no SyncAlert in SyncNotification");
return -3;
}
WCHAR* srcname = getSSourceName(APPLICATION_URI, sync->getServerURI());
if (srcname) {
if (count == 0) { cmdLine += L" "; }
else { cmdLine += L","; }
cmdLine += srcname;
delete [] srcname;
count++;
}
else {
LOG.error("CTP notification error: no source found from server notification request: %s", sync->getServerURI());
continue;
}
}
if (count == 0) {
// 0 sources to sync -> out
LOG.info("No sources to sync");
return NULL;
}
//
// Start the sync process: "startsync.exe manual <sourcename1, sourcename2,...>"
//
LOG.info("Starting sync: '%ls %ls'", app.c_str(), cmdLine.c_str());
int pid = startProgram(app.c_str(), cmdLine.c_str());
return pid;
}
/**
* Utility to extract the message length from a CTP package.
* The message length is stored in the first 2 bytes of the CTP package.
* @param package the input package
* @param packageLen the length of the passed package
* @return the message length
*/
int extractMsgLength(const char* package, int packageLen) {
if (packageLen < 2) {
LOG.error("Unable to read the package length: not enough bytes received (%d)", packageLen);
return 0;
}
int messageLen = (int)((unsigned char)package[0]);
int messageLen1 = (int)((unsigned char)package[1]);
messageLen <<= 8;
messageLen = messageLen | messageLen1;
//LOG.debug("messageLen = %d", messageLen);
return messageLen;
}
/**
* Utility function to retrieve the correspondant message for the Wininet error code passed.
* Pointer returned is allocated new, must be freed by caller.
* @param errorCode the code of the last error
* @return the error message for the passed code, new allocated buffer
*/
char* createErrorMsg(DWORD errorCode) {
WCHAR* errorMessage = new WCHAR[512];
memset(errorMessage, 0, 512);
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errorMessage,
512,
NULL);
if (!errorMessage || wcslen(errorMessage) == 0) {
wsprintf(errorMessage, L"Unknown error.");
}
char* ret = toMultibyte(errorMessage);
if (errorMessage) delete [] errorMessage;
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -