|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-10 by Raw Material Software Ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the GNU General
- Public License (Version 2), as published by the Free Software Foundation.
- A copy of the license is included in the JUCE distribution, or can be found
- online at www.gnu.org/licenses.
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.rawmaterialsoftware.com/juce for more information.
-
- ==============================================================================
- */
-
- // (This file gets included by juce_win32_NativeCode.cpp, rather than being
- // compiled on its own).
- #if JUCE_INCLUDED_FILE
-
-
- #ifndef INTERNET_FLAG_NEED_FILE
- #define INTERNET_FLAG_NEED_FILE 0x00000010
- #endif
-
- #ifndef INTERNET_OPTION_DISABLE_AUTODIAL
- #define INTERNET_OPTION_DISABLE_AUTODIAL 70
- #endif
-
- //==============================================================================
- struct ConnectionAndRequestStruct
- {
- HINTERNET connection, request;
- };
-
- static HINTERNET sessionHandle = 0;
-
- #ifndef WORKAROUND_TIMEOUT_BUG
- //#define WORKAROUND_TIMEOUT_BUG 1
- #endif
-
- #if WORKAROUND_TIMEOUT_BUG
- // Required because of a Microsoft bug in setting a timeout
- class InternetConnectThread : public Thread
- {
- public:
- InternetConnectThread (URL_COMPONENTS& uc_, HINTERNET& connection_, const bool isFtp_)
- : Thread ("Internet"), uc (uc_), connection (connection_), isFtp (isFtp_)
- {
- startThread();
- }
-
- ~InternetConnectThread()
- {
- stopThread (60000);
- }
-
- void run()
- {
- connection = InternetConnect (sessionHandle, uc.lpszHostName,
- uc.nPort, _T(""), _T(""),
- isFtp ? INTERNET_SERVICE_FTP
- : INTERNET_SERVICE_HTTP,
- 0, 0);
- notify();
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- URL_COMPONENTS& uc;
- HINTERNET& connection;
- const bool isFtp;
-
- InternetConnectThread (const InternetConnectThread&);
- InternetConnectThread& operator= (const InternetConnectThread&);
- };
- #endif
-
- void* juce_openInternetFile (const String& url,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs)
- {
- if (sessionHandle == 0)
- sessionHandle = InternetOpen (_T("juce"),
- INTERNET_OPEN_TYPE_PRECONFIG,
- 0, 0, 0);
-
- if (sessionHandle != 0)
- {
- // break up the url..
- TCHAR file[1024], server[1024];
-
- URL_COMPONENTS uc;
- zerostruct (uc);
-
- uc.dwStructSize = sizeof (uc);
- uc.dwUrlPathLength = sizeof (file);
- uc.dwHostNameLength = sizeof (server);
- uc.lpszUrlPath = file;
- uc.lpszHostName = server;
-
- if (InternetCrackUrl (url, 0, 0, &uc))
- {
- int disable = 1;
- InternetSetOption (sessionHandle, INTERNET_OPTION_DISABLE_AUTODIAL, &disable, sizeof (disable));
-
- if (timeOutMs == 0)
- timeOutMs = 30000;
- else if (timeOutMs < 0)
- timeOutMs = -1;
-
- InternetSetOption (sessionHandle, INTERNET_OPTION_CONNECT_TIMEOUT, &timeOutMs, sizeof (timeOutMs));
-
- const bool isFtp = url.startsWithIgnoreCase ("ftp:");
-
- #if WORKAROUND_TIMEOUT_BUG
- HINTERNET connection = 0;
-
- {
- InternetConnectThread connectThread (uc, connection, isFtp);
- connectThread.wait (timeOutMs);
-
- if (connection == 0)
- {
- InternetCloseHandle (sessionHandle);
- sessionHandle = 0;
- }
- }
- #else
- HINTERNET connection = InternetConnect (sessionHandle,
- uc.lpszHostName,
- uc.nPort,
- _T(""), _T(""),
- isFtp ? INTERNET_SERVICE_FTP
- : INTERNET_SERVICE_HTTP,
- 0, 0);
- #endif
-
- if (connection != 0)
- {
- if (isFtp)
- {
- HINTERNET request = FtpOpenFile (connection,
- uc.lpszUrlPath,
- GENERIC_READ,
- FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_NEED_FILE,
- 0);
-
- ConnectionAndRequestStruct* const result = new ConnectionAndRequestStruct();
- result->connection = connection;
- result->request = request;
- return result;
- }
- else
- {
- const TCHAR* mimeTypes[] = { _T("*/*"), 0 };
-
- DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES;
-
- if (url.startsWithIgnoreCase ("https:"))
- flags |= INTERNET_FLAG_SECURE; // (this flag only seems necessary if the OS is running IE6 -
- // IE7 seems to automatically work out when it's https)
-
- HINTERNET request = HttpOpenRequest (connection,
- isPost ? _T("POST")
- : _T("GET"),
- uc.lpszUrlPath,
- 0, 0, mimeTypes, flags, 0);
-
- if (request != 0)
- {
- INTERNET_BUFFERS buffers;
- zerostruct (buffers);
- buffers.dwStructSize = sizeof (INTERNET_BUFFERS);
- buffers.lpcszHeader = (LPCTSTR) headers;
- buffers.dwHeadersLength = headers.length();
- buffers.dwBufferTotal = (DWORD) postData.getSize();
- ConnectionAndRequestStruct* result = 0;
-
- if (HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0))
- {
- int bytesSent = 0;
-
- for (;;)
- {
- const int bytesToDo = jmin (1024, (int) postData.getSize() - bytesSent);
- DWORD bytesDone = 0;
-
- if (bytesToDo > 0
- && ! InternetWriteFile (request,
- static_cast <const char*> (postData.getData()) + bytesSent,
- bytesToDo, &bytesDone))
- {
- break;
- }
-
- if (bytesToDo == 0 || (int) bytesDone < bytesToDo)
- {
- result = new ConnectionAndRequestStruct();
- result->connection = connection;
- result->request = request;
-
- if (! HttpEndRequest (request, 0, 0, 0))
- break;
-
- return result;
- }
-
- bytesSent += bytesDone;
-
- if (callback != 0 && ! callback (callbackContext, bytesSent, postData.getSize()))
- break;
- }
- }
-
- InternetCloseHandle (request);
- }
-
- InternetCloseHandle (connection);
- }
- }
- }
- }
-
- return 0;
- }
-
- int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
- {
- DWORD bytesRead = 0;
- const ConnectionAndRequestStruct* const crs = static_cast <ConnectionAndRequestStruct*> (handle);
-
- if (crs != 0)
- InternetReadFile (crs->request,
- buffer, bytesToRead,
- &bytesRead);
-
- return bytesRead;
- }
-
- int juce_seekInInternetFile (void* handle, int newPosition)
- {
- if (handle != 0)
- {
- const ConnectionAndRequestStruct* const crs = static_cast <ConnectionAndRequestStruct*> (handle);
- return InternetSetFilePointer (crs->request, newPosition, 0, FILE_BEGIN, 0);
- }
-
- return -1;
- }
-
- int64 juce_getInternetFileContentLength (void* handle)
- {
- const ConnectionAndRequestStruct* const crs = static_cast <ConnectionAndRequestStruct*> (handle);
-
- if (crs != 0)
- {
- DWORD index = 0, result = 0, size = sizeof (result);
-
- if (HttpQueryInfo (crs->request, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &result, &size, &index))
- return (int64) result;
- }
-
- return -1;
- }
-
- void juce_getInternetFileHeaders (void* handle, StringPairArray& headers)
- {
- const ConnectionAndRequestStruct* const crs = static_cast <ConnectionAndRequestStruct*> (handle);
-
- if (crs != 0)
- {
- DWORD bufferSizeBytes = 4096;
-
- for (;;)
- {
- HeapBlock<char> buffer ((size_t) bufferSizeBytes);
-
- if (HttpQueryInfo (crs->request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, 0))
- {
- StringArray headersArray;
- headersArray.addLines (reinterpret_cast <const WCHAR*> (buffer.getData()));
-
- for (int i = 0; i < headersArray.size(); ++i)
- {
- const String& header = headersArray[i];
- const String key (header.upToFirstOccurrenceOf ("; ", false, false));
- const String value (header.fromFirstOccurrenceOf ("; ", false, false));
- const String previousValue (headers [key]);
-
- headers.set (key, previousValue.isEmpty() ? value : (previousValue + "," + value));
- }
-
- break;
- }
-
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- break;
- }
- }
- }
-
- void juce_closeInternetFile (void* handle)
- {
- if (handle != 0)
- {
- ScopedPointer <ConnectionAndRequestStruct> crs (static_cast <ConnectionAndRequestStruct*> (handle));
- InternetCloseHandle (crs->request);
- InternetCloseHandle (crs->connection);
- }
- }
-
- //==============================================================================
- static int getMACAddressViaGetAdaptersInfo (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numFound = 0;
-
- DynamicLibraryLoader dll ("iphlpapi.dll");
- DynamicLibraryImport (GetAdaptersInfo, getAdaptersInfo, DWORD, dll, (PIP_ADAPTER_INFO, PULONG))
-
- if (getAdaptersInfo != 0)
- {
- ULONG len = sizeof (IP_ADAPTER_INFO);
- MemoryBlock mb;
- PIP_ADAPTER_INFO adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
-
- if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW)
- {
- mb.setSize (len);
- adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
- }
-
- if (getAdaptersInfo (adapterInfo, &len) == NO_ERROR)
- {
- PIP_ADAPTER_INFO adapter = adapterInfo;
-
- while (adapter != 0)
- {
- int64 mac = 0;
- for (unsigned int i = 0; i < adapter->AddressLength; ++i)
- mac = (mac << 8) | adapter->Address[i];
-
- if (littleEndian)
- mac = (int64) ByteOrder::swap ((uint64) mac);
-
- if (numFound < maxNum && mac != 0)
- addresses [numFound++] = mac;
-
- adapter = adapter->Next;
- }
- }
- }
-
- return numFound;
- }
-
- static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numFound = 0;
-
- DynamicLibraryLoader dll ("netapi32.dll");
- DynamicLibraryImport (Netbios, NetbiosCall, UCHAR, dll, (PNCB))
-
- if (NetbiosCall != 0)
- {
- NCB ncb;
- zerostruct (ncb);
-
- struct ASTAT
- {
- ADAPTER_STATUS adapt;
- NAME_BUFFER NameBuff [30];
- };
-
- ASTAT astat;
- zeromem (&astat, sizeof (astat)); // (can't use zerostruct here in VC6)
-
- LANA_ENUM enums;
- zerostruct (enums);
-
- ncb.ncb_command = NCBENUM;
- ncb.ncb_buffer = (unsigned char*) &enums;
- ncb.ncb_length = sizeof (LANA_ENUM);
- NetbiosCall (&ncb);
-
- for (int i = 0; i < enums.length; ++i)
- {
- zerostruct (ncb);
- ncb.ncb_command = NCBRESET;
- ncb.ncb_lana_num = enums.lana[i];
-
- if (NetbiosCall (&ncb) == 0)
- {
- zerostruct (ncb);
- memcpy (ncb.ncb_callname, "* ", NCBNAMSZ);
- ncb.ncb_command = NCBASTAT;
- ncb.ncb_lana_num = enums.lana[i];
-
- ncb.ncb_buffer = (unsigned char*) &astat;
- ncb.ncb_length = sizeof (ASTAT);
-
- if (NetbiosCall (&ncb) == 0)
- {
- if (astat.adapt.adapter_type == 0xfe)
- {
- uint64 mac = 0;
- for (int i = 6; --i >= 0;)
- mac = (mac << 8) | astat.adapt.adapter_address [littleEndian ? i : (5 - i)];
-
- if (numFound < maxNum && mac != 0)
- addresses [numFound++] = mac;
- }
- }
- }
- }
- }
-
- return numFound;
- }
-
- int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian)
- {
- int numFound = getMACAddressViaGetAdaptersInfo (addresses, maxNum, littleEndian);
-
- if (numFound == 0)
- numFound = getMACAddressesViaNetBios (addresses, maxNum, littleEndian);
-
- return numFound;
- }
-
- //==============================================================================
- bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
- const String& emailSubject,
- const String& bodyText,
- const StringArray& filesToAttach)
- {
- HMODULE h = LoadLibraryA ("MAPI32.dll");
-
- typedef ULONG (WINAPI *MAPISendMailType) (LHANDLE, ULONG, lpMapiMessage, ::FLAGS, ULONG);
-
- MAPISendMailType mapiSendMail = (MAPISendMailType) GetProcAddress (h, "MAPISendMail");
- bool ok = false;
-
- if (mapiSendMail != 0)
- {
- MapiMessage message;
- zerostruct (message);
- message.lpszSubject = (LPSTR) emailSubject.toCString();
- message.lpszNoteText = (LPSTR) bodyText.toCString();
-
- MapiRecipDesc recip;
- zerostruct (recip);
- recip.ulRecipClass = MAPI_TO;
- String targetEmailAddress_ (targetEmailAddress);
- if (targetEmailAddress_.isEmpty())
- targetEmailAddress_ = " "; // (Windows Mail can't deal with a blank address)
- recip.lpszName = (LPSTR) targetEmailAddress_.toCString();
- message.nRecipCount = 1;
- message.lpRecips = &recip;
-
- HeapBlock <MapiFileDesc> files;
- files.calloc (filesToAttach.size());
-
- message.nFileCount = filesToAttach.size();
- message.lpFiles = files;
-
- for (int i = 0; i < filesToAttach.size(); ++i)
- {
- files[i].nPosition = (ULONG) -1;
- files[i].lpszPathName = (LPSTR) filesToAttach[i].toCString();
- }
-
- ok = (mapiSendMail (0, 0, &message, MAPI_DIALOG | MAPI_LOGON_UI, 0) == SUCCESS_SUCCESS);
- }
-
- FreeLibrary (h);
- return ok;
- }
-
-
- #endif
|