File indexing completed on 2025-01-12 04:20:12
0001 /// <summary> 0002 /// Snarl C++ interface implementation 0003 /// API version 42 0004 /// 0005 /// http://sourceforge.net/apps/mediawiki/snarlwin/index.php?title=Windows_API 0006 /// https://sourceforge.net/apps/mediawiki/snarlwin/index.php?title=Generic_API 0007 /// 0008 /// Written and maintained by Toke Noer Nøttrup (toke@noer.it) 0009 /// 0010 /// Please note the following changes compared to the VB6 (official API) dokumentation: 0011 /// - Function names doesn't have the prefix "sn". Naming of constants and variables are 0012 /// generally changed to follow Microsoft C# standard. This naming convention is kept for 0013 /// the C++ version, to keep them alike. 0014 /// - Grouped variables like SNARL_LAUNCHED, SNARL_QUIT is enums in SnarlEnums namespace. 0015 /// - Message events like SNARL_NOTIFICATION_CLICKED, is found in SnarlEnums::MessageEvent. 0016 /// - Please note that string functions return NULL when they fail and not an empty string. 0017 /// - Some functions in the VB API takes an appToken as first parameter. This token is a 0018 /// member variable in C++ version, so it is omitted from the functions. 0019 /// (Always call RegisterApp as first function!) 0020 /// - Functions manipulating messages (Update, Hide etc.) still takes a message token as 0021 /// parameter, but you can get the last message token calling GetLastMsgToken(); 0022 /// Example: snarl.Hide(snarl.GetLastMsgToken()); 0023 /// 0024 /// The functions in SnarlInterface both have ANSI(UTF8) and UNICODE versions. 0025 /// If the LPCWSTR (unicode) version of the functions are called, the strings 0026 /// are converted to UTF8 by SnarlInterface before sent to Snarl. So using the 0027 /// ANSI/UTF8/LPCSTR versions of the functions are faster! 0028 /// 0029 /// See https://sourceforge.net/apps/mediawiki/snarlwin/index.php?title=Windows_API#C.2B.2B 0030 /// for example code etc. 0031 /// </summary> 0032 ///---------------------------------------------------------------------------- 0033 /// <VersionHistory> 0034 /// 2011-07-31 : General update to match VB6 SVN rev. 232 0035 /// : Added AppFlags and MessagePriority enums. 0036 /// 2011-07-12 : MingW64 fixes by Hannah von Reth 0037 /// 2011-07-07 : Some changes to compile under VS2008 0038 /// - Changed vector iterators to begin/end instead of cbegin/cend 0039 /// - Removed const in PairType 0040 /// 2011-02-09 : Fix for wrong parameters in AddClass 0041 /// 2011-02-06 : Updated to rev. 3 of the wiki documentation 0042 /// 2011-02-02 : First release of V42 Snarl API implementation 0043 /// </VersionHistory> 0044 /// 0045 /// <Todo> 0046 /// </Todo> 0047 0048 #ifndef _CRT_SECURE_NO_WARNINGS 0049 #define _CRT_SECURE_NO_WARNINGS 0050 #endif 0051 0052 #include "SnarlInterface.h" 0053 0054 namespace Snarl 0055 { 0056 namespace V42 0057 { 0058 0059 // workaround for mingw-w64 bug 0060 #ifdef __MINGW64_VERSION_MAJOR 0061 extern "C" { 0062 __declspec(dllimport) errno_t __cdecl strcpy_s(char *_Dst, size_t _SizeInBytes, const char *_Src); 0063 __declspec(dllimport) errno_t __cdecl wcscpy_s(wchar_t *_Dst, size_t _SizeInBytes, const wchar_t *_Src); 0064 __declspec(dllimport) errno_t __cdecl strncat_s(char *_Dst, size_t _DstSizeInChars, const char *_Src, size_t _MaxCount); 0065 } 0066 #endif //__MINGW64_VERSION_MAJOR 0067 0068 // ---------------------------------------------------------------------------- 0069 // Static Snarl interface functions 0070 // ---------------------------------------------------------------------------- 0071 0072 UINT SnarlInterface::AppMsg() 0073 { 0074 return RegisterWindowMessage(SnarlAppMsg); 0075 } 0076 0077 UINT SnarlInterface::Broadcast() 0078 { 0079 return RegisterWindowMessage(SnarlGlobalMsg); 0080 } 0081 0082 LONG32 SnarlInterface::DoRequest(LPCSTR request, UINT replyTimeout) 0083 { 0084 DWORD_PTR nResult = 0; 0085 0086 HWND hWnd = GetSnarlWindow(); 0087 if (!IsWindow(hWnd)) { 0088 return -SnarlEnums::ErrorNotRunning; 0089 } 0090 0091 // Create COPYDATASTRUCT 0092 COPYDATASTRUCT cds; 0093 cds.dwData = 0x534E4C03; // "SNL",3 0094 cds.cbData = (DWORD)strlen(request); // No knowledge of max string length 0095 cds.lpData = const_cast<char *>(request); 0096 0097 // Send message 0098 if (SendMessageTimeout(hWnd, WM_COPYDATA, (WPARAM)GetCurrentProcessId(), (LPARAM)&cds, SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, replyTimeout, &nResult) == 0) { 0099 // Handle error 0100 DWORD nError = GetLastError(); 0101 LONG32 errorResult = 0; 0102 if (nError == ERROR_TIMEOUT) { 0103 errorResult = -SnarlEnums::ErrorTimedOut; 0104 } else { 0105 errorResult = -SnarlEnums::ErrorFailed; 0106 } 0107 0108 return errorResult; 0109 } else { 0110 return (LONG32)nResult; 0111 } 0112 } 0113 0114 LONG32 SnarlInterface::DoRequest(LPCWSTR request, UINT replyTimeout) 0115 { 0116 LONG32 nResult = 0; 0117 0118 // Convert to UTF8 0119 LPSTR utf8Request = WideToUTF8(request); 0120 if (utf8Request == NULL) { 0121 return -SnarlEnums::ErrorCppInterface; 0122 } 0123 0124 nResult = DoRequest(utf8Request, replyTimeout); 0125 0126 // Cleanup and return result 0127 FreeString(utf8Request); 0128 return nResult; 0129 } 0130 0131 std::basic_string<char> &SnarlInterface::Escape(std::basic_string<char> &str) 0132 { 0133 std::basic_string<char>::size_type strLength = str.length(); 0134 for (std::basic_string<char>::size_type i = 0; i < strLength; ++i) { 0135 if (str.at(i) == '=') { 0136 str.insert(++i, "="); 0137 ++strLength; 0138 } else if (str[i] == '&') { 0139 str.insert(++i, "&"); 0140 ++strLength; 0141 } 0142 } 0143 0144 return str; 0145 } 0146 0147 std::basic_string<wchar_t> &SnarlInterface::Escape(std::basic_string<wchar_t> &str) 0148 { 0149 std::basic_string<wchar_t>::size_type strLength = str.length(); 0150 for (std::basic_string<wchar_t>::size_type i = 0; i < strLength; ++i) { 0151 if (str.at(i) == L'=') { 0152 str.insert(++i, L"="); 0153 ++strLength; 0154 } else if (str[i] == L'&') { 0155 str.insert(++i, L"&"); 0156 ++strLength; 0157 } 0158 } 0159 0160 return str; 0161 } 0162 0163 LPCTSTR SnarlInterface::GetAppPath() 0164 { 0165 HWND hWnd = GetSnarlWindow(); 0166 if (hWnd) { 0167 HWND hWndPath = FindWindowEx(hWnd, NULL, _T("static"), NULL); 0168 if (hWndPath) { 0169 TCHAR strTmp[MAX_PATH] = {0}; 0170 int nReturn = GetWindowText(hWndPath, strTmp, MAX_PATH - 1); 0171 if (nReturn > 0) { 0172 TCHAR *strReturn = AllocateString(nReturn + 1); 0173 _tcsncpy(strReturn, strTmp, nReturn + 1); 0174 strReturn[nReturn] = 0; 0175 return strReturn; 0176 } 0177 } 0178 } 0179 0180 return NULL; 0181 } 0182 0183 LPCTSTR SnarlInterface::GetIconsPath() 0184 { 0185 TCHAR *szIconPath = NULL; 0186 LPCTSTR szPath = GetAppPath(); 0187 if (!szPath) { 0188 return NULL; 0189 } 0190 0191 size_t nLen = 0; 0192 nLen = _tcsnlen(szPath, MAX_PATH); 0193 if (nLen > 0) { 0194 nLen += 10 + 1; // etc\\icons\\ + NULL 0195 szIconPath = AllocateString(nLen); 0196 0197 _tcsncpy(szIconPath, szPath, nLen); 0198 _tcsncat(szIconPath, _T("etc\\icons\\"), nLen); 0199 } 0200 0201 FreeString(szPath); 0202 0203 return szIconPath; 0204 } 0205 0206 HWND SnarlInterface::GetSnarlWindow() 0207 { 0208 return FindWindow(SnarlWindowClass, SnarlWindowTitle);; 0209 } 0210 0211 LONG32 SnarlInterface::GetVersion() 0212 { 0213 return DoRequest(Requests::VersionA()); 0214 } 0215 0216 BOOL SnarlInterface::IsSnarlRunning() 0217 { 0218 return IsWindow(GetSnarlWindow()); 0219 } 0220 0221 // -------------------------------------------------------------------------------------------- 0222 // SnarlInterface member functions 0223 // -------------------------------------------------------------------------------------------- 0224 0225 SnarlInterface::SnarlInterface() 0226 : appToken(0), lastMsgToken(0), szPasswordA(NULL), szPasswordW(NULL) 0227 { 0228 } 0229 0230 SnarlInterface::~SnarlInterface() 0231 { 0232 delete [] szPasswordA; 0233 delete [] szPasswordW; 0234 } 0235 0236 //--------------------------------------------------------------------------------------------- 0237 0238 LONG32 SnarlInterface::AddAction(LONG32 msgToken, LPCSTR label, LPCSTR cmd) 0239 { 0240 // addaction?[token=<notification token>|app-sig=<signature>&uid=<uid>][&password=<password>]&label=<label>&cmd=<command> 0241 0242 SnarlParameterList<char> spl(4); 0243 spl.Add("token", msgToken); 0244 spl.Add("password", szPasswordA); 0245 0246 spl.Add("label", label); 0247 spl.Add("cmd", cmd); 0248 0249 return DoRequest(Requests::AddActionA(), spl); 0250 } 0251 0252 LONG32 SnarlInterface::AddAction(LONG32 msgToken, LPCWSTR label, LPCWSTR cmd) 0253 { 0254 SnarlParameterList<wchar_t> spl(4); 0255 spl.Add(L"token", msgToken); 0256 spl.Add(L"password", szPasswordW); 0257 0258 spl.Add(L"label", label); 0259 spl.Add(L"cmd", cmd); 0260 0261 return DoRequest(Requests::AddActionW(), spl); 0262 } 0263 0264 LONG32 SnarlInterface::AddClass(LPCSTR classId, LPCSTR name, LPCSTR title, LPCSTR text, LPCSTR icon, LPCSTR sound, LONG32 duration, LPCSTR callback, bool enabled) 0265 { 0266 // addclass?[app-sig=<signature>|token=<application token>][&password=<password>]&id=<class identifier>&name=<class name>[&enabled=<0|1>][&callback=<callback>] 0267 // [&title=<title>][&text=<text>][&icon=<icon>][&sound=<sound>][&duration=<duration>] 0268 0269 SnarlParameterList<char> spl(11); 0270 spl.Add("token", appToken); 0271 spl.Add("password", szPasswordA); 0272 0273 spl.Add("id", classId); 0274 spl.Add("name", name); 0275 spl.Add("enabled", enabled); 0276 spl.Add("callback", callback); 0277 spl.Add("title", title); 0278 spl.Add("text", text); 0279 spl.Add("icon", icon); 0280 spl.Add("sound", sound); 0281 if (duration != -1) { 0282 spl.Add("duration", duration); 0283 } 0284 0285 return DoRequest(Requests::AddClassA(), spl); 0286 } 0287 0288 LONG32 SnarlInterface::AddClass(LPCWSTR classId, LPCWSTR name, LPCWSTR title, LPCWSTR text, LPCWSTR icon, LPCWSTR sound, LONG32 duration, LPCWSTR callback, bool enabled) 0289 { 0290 SnarlParameterList<wchar_t> spl(11); 0291 spl.Add(L"token", appToken); 0292 spl.Add(L"password", szPasswordW); 0293 0294 spl.Add(L"id", classId); 0295 spl.Add(L"name", name); 0296 spl.Add(L"enabled", enabled); 0297 spl.Add(L"callback", callback); 0298 spl.Add(L"title", title); 0299 spl.Add(L"text", text); 0300 spl.Add(L"icon", icon); 0301 spl.Add(L"sound", sound); 0302 if (duration != -1) { 0303 spl.Add(L"duration", duration); 0304 } 0305 0306 return DoRequest(Requests::AddClassW(), spl); 0307 } 0308 0309 LONG32 SnarlInterface::ClearActions(LONG32 msgToken) 0310 { 0311 // clearactions?[token=<notification token>|app-sig=<app-sig>&uid=<uid>][&password=<password>] 0312 0313 SnarlParameterList<char> spl(2); 0314 spl.Add("token", msgToken); 0315 spl.Add("password", szPasswordA); 0316 0317 return DoRequest(Requests::ClearActionsA(), spl); 0318 } 0319 0320 LONG32 SnarlInterface::ClearClasses() 0321 { 0322 // clearclasses?[token=app-sig=<signature>|token=<application token>][&password=<password>] 0323 0324 SnarlParameterList<char> spl(2); 0325 spl.Add("token", appToken); 0326 spl.Add("password", szPasswordA); 0327 0328 return DoRequest(Requests::ClearClassesA(), spl); 0329 } 0330 0331 LONG32 SnarlInterface::GetLastMsgToken() const 0332 { 0333 return lastMsgToken; 0334 } 0335 0336 LONG32 SnarlInterface::Hide(LONG32 msgToken) 0337 { 0338 // hide?[token=<notification token>|app-sig=<app-sig>&uid=<uid>][&password=<password>] 0339 0340 SnarlParameterList<char> spl(2); 0341 spl.Add("token", msgToken); 0342 spl.Add("password", szPasswordA); 0343 0344 return DoRequest(Requests::HideA(), spl); 0345 } 0346 0347 LONG32 SnarlInterface::IsVisible(LONG32 msgToken) 0348 { 0349 // isvisible?[token=<notification token>|app-sig=<app-sig>&uid=<uid>][&password=<password>] 0350 0351 SnarlParameterList<char> spl(2); 0352 spl.Add("token", msgToken); 0353 spl.Add("password", szPasswordA); 0354 0355 return DoRequest(Requests::IsVisibleA(), spl); 0356 } 0357 0358 LONG32 SnarlInterface::Notify(LPCSTR classId, LPCSTR title, LPCSTR text, LONG32 timeout, LPCSTR iconPath, LPCSTR iconBase64, SnarlEnums::MessagePriority priority, LPCSTR uid, LPCSTR callback, LPCSTR value) 0359 { 0360 // notify?[app-sig=<signature>|token=<application token>][&password=<password>][&id=<class identifier>] 0361 // [&title=<title>][&text=<text>][&timeout=<timeout>][&icon=<icon path>][&icon-base64=<MIME data>][&callback=<default callback>] 0362 // [&priority=<priority>][&uid=<notification uid>][&value=<value>] 0363 0364 SnarlParameterList<char> spl(12); 0365 spl.Add("token", appToken); 0366 spl.Add("password", szPasswordA); 0367 0368 spl.Add("id", classId); 0369 spl.Add("title", title); 0370 spl.Add("text", text); 0371 spl.Add("icon", iconPath); 0372 spl.Add("icon-base64", iconBase64); 0373 spl.Add("uid", uid); 0374 spl.Add("callback", callback); 0375 spl.Add("value", value); 0376 if (timeout != -1) { 0377 spl.Add("timeout", timeout); 0378 } 0379 if (priority != SnarlEnums::PriorityUndefined) { 0380 spl.Add("priority", priority); // -1 is a legal priority 0381 } 0382 0383 LONG32 request = DoRequest(Requests::NotifyA(), spl); 0384 lastMsgToken = (request > 0) ? request : 0; 0385 0386 return request; 0387 } 0388 0389 LONG32 SnarlInterface::Notify(LPCWSTR classId, LPCWSTR title, LPCWSTR text, LONG32 timeout, LPCWSTR iconPath, LPCWSTR iconBase64, SnarlEnums::MessagePriority priority, LPCWSTR uid, LPCWSTR callback, LPCWSTR value) 0390 { 0391 SnarlParameterList<wchar_t> spl(12); 0392 spl.Add(L"token", appToken); 0393 spl.Add(L"password", szPasswordW); 0394 0395 spl.Add(L"id", classId); 0396 spl.Add(L"title", title); 0397 spl.Add(L"text", text); 0398 spl.Add(L"icon", iconPath); 0399 spl.Add(L"icon-base64", iconBase64); 0400 spl.Add(L"uid", uid); 0401 spl.Add(L"callback", callback); 0402 spl.Add(L"value", value); 0403 if (timeout != -1) { 0404 spl.Add(L"timeout", timeout); 0405 } 0406 if (priority != SnarlEnums::PriorityUndefined) { 0407 spl.Add(L"priority", priority); // -1 is a legal priority 0408 } 0409 0410 LONG32 request = DoRequest(Requests::NotifyW(), spl); 0411 lastMsgToken = (request > 0) ? request : 0; 0412 0413 return request; 0414 } 0415 0416 LONG32 SnarlInterface::Register(LPCSTR signature, LPCSTR title, LPCSTR icon, LPCSTR password, HWND hWndReplyTo, LONG32 msgReply, SnarlEnums::AppFlags flags) 0417 { 0418 // register?app-sig=<signature>&title=<title>[&icon=<icon>][&password=<password>][&reply-to=<reply window>][&reply=<reply message>] 0419 0420 SnarlParameterList<char> spl(6); 0421 spl.Add("app-sig", signature); 0422 spl.Add("title", title); 0423 spl.Add("icon", icon); 0424 spl.Add("password", password); 0425 spl.Add("reply-to", hWndReplyTo); 0426 spl.Add("reply", msgReply); 0427 spl.Add("flags", flags); 0428 0429 // If password was given, save and use in all other functions requiring password 0430 if (password != NULL && strlen(password) > 0) { 0431 SetPassword(password); 0432 } 0433 0434 LONG32 request = DoRequest(Requests::RegisterA(), spl); 0435 if (request > 0) { 0436 appToken = request; 0437 } 0438 0439 return request; 0440 } 0441 0442 LONG32 SnarlInterface::Register(LPCWSTR signature, LPCWSTR name, LPCWSTR icon, LPCWSTR password, HWND hWndReplyTo, LONG32 msgReply, SnarlEnums::AppFlags flags) 0443 { 0444 SnarlParameterList<wchar_t> spl(7); 0445 spl.Add(L"app-sig", signature); 0446 spl.Add(L"title", name); 0447 spl.Add(L"icon", icon); 0448 spl.Add(L"password", password); 0449 spl.Add(L"reply-to", hWndReplyTo); 0450 spl.Add(L"reply", msgReply); 0451 spl.Add(L"flags", flags); 0452 0453 // If password was given, save and use in all other functions requiring password 0454 if (password != NULL && wcslen(password) > 0) { 0455 SetPassword(password); 0456 } 0457 0458 LONG32 request = DoRequest(Requests::RegisterW(), spl); 0459 if (request > 0) { 0460 appToken = request; 0461 } 0462 0463 return request; 0464 } 0465 0466 LONG32 SnarlInterface::RemoveClass(LPCSTR classId) 0467 { 0468 // remclass?[app-sig=<signature>|token=<application token>][&password=<password>][&id=<class identifier>|&all=<0|1>] 0469 0470 SnarlParameterList<char> spl(3); 0471 spl.Add("token", appToken); 0472 spl.Add("password", szPasswordA); 0473 0474 spl.Add("id", classId); 0475 // instead of all, use ClearClasses 0476 0477 return DoRequest(Requests::RemoveClassA(), spl); 0478 } 0479 0480 LONG32 SnarlInterface::RemoveClass(LPCWSTR classId) 0481 { 0482 SnarlParameterList<wchar_t> spl(3); 0483 spl.Add(L"token", appToken); 0484 spl.Add(L"password", szPasswordW); 0485 0486 spl.Add(L"id", classId); 0487 0488 return DoRequest(Requests::RemoveClassW(), spl); 0489 } 0490 0491 LONG32 SnarlInterface::Unregister(LPCSTR signature) 0492 { 0493 // unregister?[app-sig=<signature>|token=<application token>][&password=<password>] 0494 0495 SnarlParameterList<char> spl(2); 0496 spl.Add("app-sig", signature); 0497 spl.Add("password", szPasswordA); 0498 0499 appToken = 0; 0500 lastMsgToken = 0; 0501 ClearPassword(); 0502 0503 return DoRequest(Requests::UnregisterA(), spl); 0504 } 0505 0506 LONG32 SnarlInterface::Unregister(LPCWSTR signature) 0507 { 0508 SnarlParameterList<wchar_t> spl(2); 0509 spl.Add(L"app-sig", signature); 0510 spl.Add(L"password", szPasswordW); 0511 0512 appToken = 0; 0513 lastMsgToken = 0; 0514 ClearPassword(); 0515 0516 return DoRequest(Requests::UnregisterW(), spl); 0517 } 0518 0519 LONG32 SnarlInterface::Update(LONG32 msgToken, LPCSTR classId, LPCSTR title, LPCSTR text, LONG32 timeout, LPCSTR iconPath, LPCSTR iconBase64, SnarlEnums::MessagePriority priority, LPCSTR callback, LPCSTR value) 0520 { 0521 // Made from best guess - no documentation available yet 0522 SnarlParameterList<char> spl(11); 0523 spl.Add("token", msgToken); 0524 spl.Add("password", szPasswordA); 0525 0526 spl.Add("id", classId); 0527 spl.Add("title", title); 0528 spl.Add("text", text); 0529 spl.Add("icon", iconPath); 0530 spl.Add("icon-base64", iconBase64); 0531 spl.Add("callback", callback); 0532 spl.Add("value", value); 0533 if (timeout != -1) { 0534 spl.Add("timeout", timeout); 0535 } 0536 if (priority != SnarlEnums::PriorityUndefined) { 0537 spl.Add("priority", priority); // -1 is a legal priority 0538 } 0539 0540 return DoRequest(Requests::UpdateA(), spl); 0541 } 0542 0543 LONG32 SnarlInterface::Update(LONG32 msgToken, LPCWSTR classId, LPCWSTR title, LPCWSTR text, LONG32 timeout, LPCWSTR iconPath, LPCWSTR iconBase64, SnarlEnums::MessagePriority priority, LPCWSTR callback, LPCWSTR value) 0544 { 0545 // Made from best guess - no documentation available yet 0546 SnarlParameterList<wchar_t> spl(11); 0547 spl.Add(L"token", msgToken); 0548 spl.Add(L"password", szPasswordW); 0549 0550 spl.Add(L"id", classId); 0551 spl.Add(L"title", title); 0552 spl.Add(L"text", text); 0553 spl.Add(L"icon", iconPath); 0554 spl.Add(L"icon-base64", iconBase64); 0555 spl.Add(L"callback", callback); 0556 spl.Add(L"value", value); 0557 if (timeout != -1) { 0558 spl.Add(L"timeout", timeout); 0559 } 0560 if (priority != SnarlEnums::PriorityUndefined) { 0561 spl.Add(L"priority", priority); // -1 is a legal priority 0562 } 0563 0564 return DoRequest(Requests::UpdateW(), spl); 0565 } 0566 0567 /* 0568 // Update app should not be used at this time, according to wiki 0569 LONG32 SnarlInterface::UpdateApp(LPCSTR title, LPCSTR icon) 0570 { 0571 SnarlParameterList<char> spl(3); 0572 spl.Add("token", appToken); 0573 spl.Add("title", title); 0574 spl.Add("icon", icon); 0575 0576 return DoRequest(Requests::UpdateAppA(), spl); 0577 } 0578 0579 LONG32 SnarlInterface::UpdateApp(LPCWSTR title, LPCWSTR icon) 0580 { 0581 SnarlParameterList<wchar_t> spl(2); 0582 spl.Add(L"token", appToken); 0583 spl.Add(L"title", title); 0584 spl.Add(L"icon", icon); 0585 0586 return DoRequest(Requests::UpdateAppW(), spl); 0587 }*/ 0588 0589 //----------------------------------------------------------------------------- 0590 // Private functions 0591 //----------------------------------------------------------------------------- 0592 0593 LONG32 SnarlInterface::DoRequest(LPCSTR request, SnarlParameterList<char> &spl, UINT replyTimeout) 0594 { 0595 // <action>[?<data>=<value>[&<data>=<value>]] 0596 const std::vector<SnarlParameterList<char>::PairType> &list = spl.GetList(); 0597 0598 if (list.size() > 0) { 0599 std::string requestStr = request; 0600 requestStr.append("?"); 0601 0602 std::vector<SnarlParameterList<char>::PairType>::const_iterator listEnd = list.end(); // cend(); 0603 for (std::vector<SnarlParameterList<char>::PairType>::const_iterator iter = list.begin(); // cbegin(); 0604 iter != listEnd; ++iter) { 0605 SnarlParameterList<char>::PairType pair = *iter; 0606 0607 if (iter->second.length() > 0) { 0608 std::basic_string<char> &value = const_cast<std::basic_string<char>&>(iter->second); 0609 requestStr.append(iter->first).append("=").append(Escape(value)); 0610 requestStr.append("&"); 0611 } 0612 } 0613 // Delete last & 0614 requestStr.erase(requestStr.size() - 1); 0615 0616 return DoRequest(requestStr.c_str(), replyTimeout); 0617 } else { 0618 return DoRequest(request, replyTimeout); 0619 } 0620 } 0621 0622 LONG32 SnarlInterface::DoRequest(LPCWSTR request, SnarlParameterList<wchar_t> &spl, UINT replyTimeout) 0623 { 0624 // <action>[?<data>=<value>[&<data>=<value>]] 0625 const std::vector<SnarlParameterList<wchar_t>::PairType> &list = spl.GetList(); 0626 0627 if (list.size() > 0) { 0628 std::basic_string<wchar_t> requestStr = request; 0629 requestStr.append(L"?"); 0630 0631 std::vector<SnarlParameterList<wchar_t>::PairType>::const_iterator listEnd = list.end(); // cend(); 0632 for (std::vector<SnarlParameterList<wchar_t>::PairType>::const_iterator iter = list.begin(); // cbegin(); 0633 iter != listEnd; ++iter) { 0634 if (iter->second.length() > 0) { 0635 std::basic_string<wchar_t> &value = const_cast<std::basic_string<wchar_t>&>(iter->second); 0636 requestStr.append(iter->first).append(L"=").append(Escape(value)); 0637 requestStr.append(L"&"); 0638 } 0639 } 0640 // Delete last & 0641 requestStr.erase(requestStr.size() - 1); 0642 0643 return DoRequest(requestStr.c_str(), replyTimeout); 0644 } else { 0645 return DoRequest(request, replyTimeout); 0646 } 0647 } 0648 0649 // Remember to delete [] returned string 0650 LPSTR SnarlInterface::WideToUTF8(LPCWSTR szWideStr) 0651 { 0652 if (szWideStr == NULL) { 0653 return NULL; 0654 } 0655 0656 int nSize = WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, NULL, 0, NULL, NULL); 0657 LPSTR szUTF8 = new char[nSize]; 0658 WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, szUTF8, nSize, NULL, NULL); 0659 0660 return szUTF8; 0661 } 0662 0663 void SnarlInterface::SetPassword(LPCSTR password) 0664 { 0665 ClearPassword(); 0666 0667 if (password != NULL) { 0668 int bufSize = (int)strlen(password) + 1; 0669 szPasswordA = new char[bufSize]; 0670 szPasswordW = new wchar_t[bufSize]; 0671 0672 // Copy ansi string 0673 strcpy_s(szPasswordA, bufSize, password); 0674 0675 // Copy wide string 0676 MultiByteToWideChar(CP_ACP, 0, password, bufSize, szPasswordW, bufSize); 0677 } 0678 } 0679 0680 void SnarlInterface::SetPassword(LPCWSTR password) 0681 { 0682 ClearPassword(); 0683 0684 if (password != NULL) { 0685 size_t bufSize = wcslen(password) + 1; 0686 szPasswordW = new wchar_t[bufSize]; 0687 0688 // Copy wide string 0689 wcscpy_s(szPasswordW, bufSize, password); 0690 0691 // Copy ansi string 0692 szPasswordA = WideToUTF8(password); 0693 } 0694 } 0695 0696 void SnarlInterface::ClearPassword() 0697 { 0698 // Safe to delete NULL 0699 delete [] szPasswordA; 0700 delete [] szPasswordW; 0701 szPasswordA = NULL; 0702 szPasswordW = NULL; 0703 } 0704 0705 } 0706 } // namespace Snarl::V42 0707