void SharedArrayRawBuffer::dropReference() { // Drop the reference to the buffer. uint32_t refcount = --this->refcount; // Atomic. // If this was the final reference, release the buffer. if (refcount == 0) { SharedMem<uint8_t*> p = this->dataPointerShared() - AsmJSPageSize; MOZ_ASSERT(p.asValue() % AsmJSPageSize == 0); uint8_t* address = p.unwrap(/*safe - only reference*/); #if defined(ASMJS_MAY_USE_SIGNAL_HANDLERS_FOR_OOB) numLive--; UnmapMemory(address, SharedArrayMappedSize); # if defined(MOZ_VALGRIND) \ && defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE) // Tell Valgrind/Memcheck to recommence reporting accesses in the // previously-inaccessible region. VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(address, SharedArrayMappedSize); # endif #else UnmapMemory(address, this->length + AsmJSPageSize); #endif } }
void SharedArrayRawBuffer::dropReference() { // Drop the reference to the buffer. uint32_t refcount = --this->refcount_; // Atomic. if (refcount) return; // If this was the final reference, release the buffer. SharedMem<uint8_t*> p = this->dataPointerShared() - gc::SystemPageSize(); MOZ_ASSERT(p.asValue() % gc::SystemPageSize() == 0); uint8_t* address = p.unwrap(/*safe - only reference*/); uint32_t allocSize = SharedArrayAllocSize(this->length); if (this->preparedForAsmJS) { numLive--; uint32_t mappedSize = SharedArrayMappedSize(allocSize); UnmapMemory(address, mappedSize); # if defined(MOZ_VALGRIND) && defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE) // Tell Valgrind/Memcheck to recommence reporting accesses in the // previously-inaccessible region. VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(address, mappedSize); # endif } else { UnmapMemory(address, allocSize); } }
/// Makes the LocalConnection object listen. /// /// The name is a symbolic name like "lc1", that is used by the /// send() command to signify which local connection to send the /// object to. // /// When connect is called, this object adds its domain + name plus some /// other bits of information to the listeners portion of the shared memory. /// It also sets the initial bytes of the shared memory to a set /// pattern. // /// The connection will fail if a listener with the same id (domain + name) /// already exists. ActionScript isn't informed of this failure. void LocalConnection_as::connect(const std::string& name) { assert(!name.empty()); _name = name; if (!_shm.attach()) { log_error("Failed to open shared memory segment"); return; } SharedMem::iterator ptr = _shm.begin(); // We can't connect if there is already a listener with the same name. if (!addListener(_domain + ":" + _name, _shm)) { return; } const char i[] = { 1, 0, 0, 0, 1, 0, 0, 0 }; std::copy(i, i + 8, ptr); movie_root& mr = getRoot(owner()); mr.addAdvanceCallback(this); _connected = true; return; }
void Dow::Handle::SendInterprocessPackage (RegisteredMessage & msg) const { unsigned int packageLen = msg.GetWParam (); void const * package = reinterpret_cast<void const *>(msg.GetLParam ()); Assert (package != 0); SharedMem buf (packageLen); GlobalAtom memName (buf.GetName ().c_str ()); if (!memName.IsOK ()) throw Exception ("Internal error: Cannot prepare interprocess package"); memcpy (&buf [0], package, packageLen); UserMessage ipcMsg (UM_INTERPROCESS_PACKAGE, msg.GetMsg (), memName.GetAtom ()); SendMsg (ipcMsg); msg.SetResult (ipcMsg.GetResult ()); }
void SharedArrayRawBuffer::dropReference() { // Normally if the refcount is zero then the memory will have been unmapped // and this test may just crash, but if the memory has been retained for any // reason we will catch the underflow here. MOZ_RELEASE_ASSERT(this->refcount_ > 0); // Drop the reference to the buffer. uint32_t refcount = --this->refcount_; // Atomic. if (refcount) return; // If this was the final reference, release the buffer. #ifdef DEBUG liveBuffers_--; #endif SharedMem<uint8_t*> p = this->dataPointerShared() - gc::SystemPageSize(); MOZ_ASSERT(p.asValue() % gc::SystemPageSize() == 0); uint8_t* address = p.unwrap(/*safe - only reference*/); uint32_t allocSize = SharedArrayAllocSize(this->length); if (this->preparedForAsmJS) { numLive--; uint32_t mappedSize = SharedArrayMappedSize(allocSize); UnmapMemory(address, mappedSize); # if defined(MOZ_VALGRIND) && defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE) // Tell Valgrind/Memcheck to recommence reporting accesses in the // previously-inaccessible region. VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(address, mappedSize); # endif } else { UnmapMemory(address, allocSize); } }
void LocalConnection_as::update() { // Check whether local connection is disabled(!): brilliant choice of // function name. if (rcfile.getLocalConnection()) { log_security("Attempting to write to disabled LocalConnection!"); movie_root& mr = getRoot(owner()); mr.removeAdvanceCallback(this); return; } // No-op if already attached. Nothing to do if it fails, but we // should probably stop trying. if (!_shm.attach()) { log_error("Failed to attach shared memory segment"); return; } // We need the lock to prevent simultaneous reads/writes from other // processes. SharedMem::Lock lock(_shm); if (!lock.locked()) { log_debug("Failed to get shm lock"); return; } SharedMem::iterator ptr = _shm.begin(); // First check timestamp data. // These are not network byte order by default, but not sure about // host byte order. const boost::uint32_t timestamp = readLong(ptr + 8); const boost::uint32_t size = readLong(ptr + 12); // As long as there is a timestamp in the shared memory, we mustn't // write anything. // // We check if this is data we are listening for. If it is, read it and // mark for overwriting. // // If not, we keep checking until the data has been overwritten by // another listener or until it's expired. If it's expired, we // mark for overwriting. if (timestamp) { // Start after 16-byte header. const boost::uint8_t* b = ptr + 16; // End at reported size of AMF sequence. const boost::uint8_t* end = b + size; amf::Reader rd(b, end, getGlobal(owner())); as_value a; // Get the connection name. That's all we need to remove expired // data. if (!rd(a)) { log_error("Invalid connection name data"); return; } const std::string& connection = a.to_string(); // Now check if data we wrote has expired. There's no really // reliable way of checking that we genuinely wrote it. if (_lastTime == timestamp) { const size_t timeout = 4 * 1000; VM& vm = getVM(owner()); const boost::uint32_t timeNow = getTimestamp(vm); if (timeNow - timestamp > timeout) { log_debug("Data %s expired at %s. Removing its target " "as a listener", timestamp, timeNow); removeListener(connection, _shm); markRead(_shm); _lastTime = 0; } } // If we are listening and the data is for us, get the rest of it // and call the method. if (_connected && connection == _domain + ":" + _name) { executeAMFFunction(owner(), rd); // Zero the timestamp bytes to signal that the shared memory // can be written again. markRead(_shm); } else { // The data has not expired and we didn't read it. Leave it // alone until it's expired or someone else has read it. return; } } // If we have no data to send, there's nothing more to do. if (_queue.empty()) { // ...except remove the callback if we aren't listening for anything. if (!_connected) { movie_root& mr = getRoot(owner()); mr.removeAdvanceCallback(this); } return; } // Get the first buffer. boost::shared_ptr<ConnectionData> cd = _queue.front(); _queue.pop_front(); // If the correct listener isn't there, iterate until we find one or // there aren't any left. while (!findListener(_domain + ":" + cd->name, _shm)) { if (_queue.empty()) { // Make sure we send the empty header later. cd->ts = 0; break; } cd = _queue.front(); _queue.pop_front(); } // Yes, there is data to send. const char i[] = { 1, 0, 0, 0, 1, 0, 0, 0 }; std::copy(i, i + arraySize(i), ptr); SimpleBuffer& buf = cd->data; SharedMem::iterator tmp = ptr + 8; writeLong(tmp, cd->ts); writeLong(tmp, cd->ts ? buf.size() : 0); std::copy(buf.data(), buf.data() + buf.size(), tmp); // Note the timestamp of our last send. We will keep calling update() // until the data has expired or been read. _lastTime = cd->ts; }
int main(int argc, char *argv[]) { void sigint_handler(int sig); /* prototype */ if(signal(SIGINT,sigint_handler) == SIG_ERR) { MWLOG(LEV_ERROR, MOD_DLG, L" %s setup of signal handler : %s ", argv[0], strerror(errno) ); exit(DLG_ERR); } int iRet = DLG_CANCEL; // parse the arguments according to the operation requested MWLOG(LEV_INFO, MOD_DLG, L" Running %s ...",argv[0]); if(argc > 2 ) { int iFunctionIndex = atoi(argv[1]); std::string readableFilePath = argv[2]; if(iFunctionIndex == DLG_ASK_PIN) { QApplication a(argc, argv); // attach to the segment and get a pointer DlgAskPINArguments *oData = NULL; SharedMem oShMemory; oShMemory.Attach( sizeof(DlgAskPINArguments), readableFilePath.c_str(),(void **) &oData); // do something dlgWndAskPIN *dlg = NULL; try { QString PINName; if( oData->usage == DLG_PIN_UNKNOWN ) { PINName = QString::fromWCharArray(oData->pinName); } else { PINName = GETQSTRING_DLG(Pin); } QString Header; switch( oData->operation ) { case DLG_PIN_OP_VERIFY: switch( oData->usage ) { case DLG_PIN_AUTH: Header = GETQSTRING_DLG(PleaseEnterYourPin); Header += ", "; Header += GETQSTRING_DLG(InOrderToAuthenticateYourself); Header += "\n"; break; case DLG_PIN_SIGN: Header = GETQSTRING_DLG(Caution); Header += " "; Header += GETQSTRING_DLG(YouAreAboutToMakeALegallyBindingElectronic); Header += "\n"; Header += GETQSTRING_DLG(PleaseEnterYourPin); Header += ", "; Header += GETQSTRING_DLG(ToContinueOrClickTheCancelButton); Header += "\n\n"; Header += GETQSTRING_DLG(Warning); Header += " "; Header += GETQSTRING_DLG(IfYouOnlyWantToLogOnToA); Header += "\n"; break; default: Header = GETQSTRING_DLG(PleaseEnterYourPin); Header += "\n"; break; } break; case DLG_PIN_OP_UNBLOCK_NO_CHANGE: Header = GETQSTRING_DLG(PleaseEnterYourPuk); Header += ", "; Header = GETQSTRING_DLG(ToUnblock); Header += " "; Header = GETQSTRING_DLG(Your); Header += " \""; if( wcslen(oData->pinName)==0 ) { Header += QString::fromWCharArray(oData->pinName); } else { Header += GETQSTRING_DLG(Pin); } Header += "\"\n"; break; default: oData->returnValue = DLG_BAD_PARAM; oShMemory.Detach((void *)oData); return 0; break; } dlg = new dlgWndAskPIN( oData->pinInfo, oData->usage, Header, PINName, DlgGetKeyPad() ); int retVal = dlg->exec(); if( retVal == QDialog::Accepted ) { wcscpy_s(oData->pin, sizeof(oData->pin)/sizeof(wchar_t), dlg->getPIN().c_str()); oData->returnValue = DLG_OK; } else // we'll consider as cancel { oData->returnValue = DLG_CANCEL; } delete dlg; dlg = NULL; oShMemory.Detach((void *)oData); return 0; } catch( ... ) { if( dlg ) delete dlg; oData->returnValue = DLG_ERR; oShMemory.Detach((void *)oData); return 0; } } else if (iFunctionIndex == DLG_ASK_PINS ) { QApplication a(argc, argv); // attach to the segment and get a pointer DlgAskPINsArguments *oData = NULL; SharedMem oShMemory; oShMemory.Attach( sizeof(DlgAskPINsArguments), readableFilePath.c_str(),(void **) &oData); dlgWndAskPINs *dlg = NULL; try { QString PINName; QString Header; Header = GETQSTRING_DLG(EnterYour); Header += " "; switch( oData->operation ) { case DLG_PIN_OP_CHANGE: if( oData->usage == DLG_PIN_UNKNOWN ) { PINName = QString::fromWCharArray(oData->pinName); } else { PINName = GETQSTRING_DLG(Pin); } break; case DLG_PIN_OP_UNBLOCK_CHANGE: if( oData->usage == DLG_PIN_UNKNOWN ) { PINName = QString::fromWCharArray(oData->pinName); } else { PINName = GETQSTRING_DLG(Puk); } break; default: oData->returnValue = DLG_BAD_PARAM; oShMemory.Detach((void *)oData); return 0; break; } Header += PINName; Header += " "; Header += GETQSTRING_DLG(Code); dlg = new dlgWndAskPINs( oData->pin1Info, oData->pin2Info, Header, PINName, DlgGetKeyPad() ); if( dlg->exec() ) { wcscpy_s(oData->pin1, sizeof(oData->pin1)/sizeof(wchar_t), dlg->getPIN1().c_str()); wcscpy_s(oData->pin2, sizeof(oData->pin2)/sizeof(wchar_t), dlg->getPIN2().c_str()); delete dlg; dlg = NULL; oData->returnValue = DLG_OK; oShMemory.Detach((void *)oData); return 0; } delete dlg; dlg = NULL; } catch( ... ) { if( dlg ) delete dlg; oData->returnValue = DLG_ERR; oShMemory.Detach((void *)oData); return 0; } oData->returnValue = DLG_CANCEL; oShMemory.Detach((void *)oData); return 0; } else if (iFunctionIndex == DLG_BAD_PIN) { QApplication a(argc, argv); // attach to the segment and get a pointer DlgBadPinArguments *oData = NULL; SharedMem oShMemory; oShMemory.Attach( sizeof(DlgBadPinArguments), readableFilePath.c_str(),(void **) &oData); dlgWndBadPIN *dlg = NULL; try { QString PINName; switch( oData->usage ) { case DLG_PIN_UNKNOWN: if( wcscmp(oData->pinName,L"") == 0 ) { return 0; } PINName = QString::fromWCharArray(oData->pinName); break; default: if( wcscmp(oData->pinName,L"") == 0 ) { PINName = GETQSTRING_DLG(Pin); } else { PINName = QString::fromWCharArray(oData->pinName); } break; } dlg = new dlgWndBadPIN( PINName, oData->ulRemainingTries ); if( dlg->exec() ) { delete dlg; dlg = NULL; eIDMW::DlgRet dlgResult = DLG_RETRY; if( oData->ulRemainingTries == 0 ) { dlgResult = DLG_OK; } oData->returnValue = dlgResult; oShMemory.Detach((void *)oData); return 0; } delete dlg; dlg = NULL; } catch( ... ) { if( dlg ) delete dlg; oData->returnValue = DLG_ERR; oShMemory.Detach((void *)oData); return 0; } oData->returnValue = DLG_CANCEL; oShMemory.Detach((void *)oData); return 0; } else if (iFunctionIndex == DLG_DISPLAY_PINPAD_INFO) { //To avoid problem on Mac Leopard, we follow these steps //1. The server is call with the 2 usual param //2. A fork is made //2a. The fork process recall the QtServer with a 3rd parameter //2b. The main process get the child pid and write it into the share memory and then quit //3. The Child process show the dialog SharedMem oShMemory; if(argc == 3 ) { MWLOG(LEV_DEBUG, MOD_DLG,L" %s called with DLG_DISPLAY_PINPAD_INFO",argv[0]); char csCommand[100]; sprintf(csCommand,"%s %s %s child",argv[0], argv[1], argv[2]); // spawn a child process signal(SIGCHLD,SIG_IGN); pid_t pid = fork(); if(pid == -1) { MWLOG(LEV_ERROR, MOD_DLG, L" %s fork : %s ", argv[0], strerror(errno) ); exit(DLG_ERR); } if(pid == 0) { // // fork process // MWLOG(LEV_DEBUG, MOD_DLG, L" %s fork process started", argv[0]); //Due to Mac Leopard constraint, we start another QtServer //See __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__ int code = system(csCommand); if(code != 0) { MWLOG(LEV_ERROR, MOD_DLG, L" eIDMW::CallQTServer %s %s child : %s ",argv[1], argv[2], strerror(errno) ); exit(DLG_ERR); } MWLOG(LEV_DEBUG, MOD_DLG, L" %s fork system() return", argv[0]); return 0; } else { // // parent process // MWLOG(LEV_DEBUG, MOD_DLG, L" %s started fork process with ID %d", argv[0], pid); pid_t subpid=0; for(int i=0;i<10;i++) { CThread::SleepMillisecs(100); //Wait for the child process to start if(0 != (subpid = getPidFromParentid(pid, csCommand))) { break; } } oShMemory.Attach( sizeof(DlgDisplayPinpadInfoArguments), readableFilePath.c_str(),(void **) &oInfoData); if(subpid == 0) { MWLOG(LEV_ERROR, MOD_DLG, L" %s failed to find child process ID", argv[0]); oInfoData->returnValue = DLG_ERR; } else { MWLOG(LEV_DEBUG, MOD_DLG, L" %s find child process whit ID %ld", argv[0], subpid); oInfoData->tRunningProcess = subpid; oInfoData->returnValue = DLG_OK; } oShMemory.Detach((void *)oInfoData); return 0; } } else { // // child process // oShMemory.Attach( sizeof(DlgDisplayPinpadInfoArguments), readableFilePath.c_str(),(void **) &oInfoData); MWLOG(LEV_DEBUG, MOD_DLG, L" %s child process started (pin=%ls, usage=%ld, operation=%ld)", argv[0],oInfoData->pinName, oInfoData->usage, oInfoData->operation); QApplication a(argc, argv); MWLOG(LEV_DEBUG, MOD_DLG, L" %s child process : QApplication created", argv[0]); // attach to the segment and get a pointer try { QString qsReader=QString::fromWCharArray(oInfoData->reader); QString qsPinName=QString::fromWCharArray(oInfoData->pinName); QString qsMessage=QString::fromWCharArray(oInfoData->message); QString PINName; switch( oInfoData->usage ) { case DLG_PIN_UNKNOWN: if( wcscmp(oInfoData->pinName,L"") == 0 ) { return 0; } PINName = QString::fromWCharArray(oInfoData->pinName); break; default: if( wcscmp(oInfoData->pinName,L"") == 0 ) { PINName = GETQSTRING_DLG(Pin); } else { PINName = QString::fromWCharArray(oInfoData->pinName); } break; } MWLOG(LEV_DEBUG, MOD_DLG, L" %s child process : pin name set", argv[0]); if(qsMessage.isEmpty()) { switch( oInfoData->operation ) { case DLG_PIN_OP_VERIFY: switch( oInfoData->usage ) { case DLG_PIN_AUTH: qsMessage = GETQSTRING_DLG(PleaseEnterYourPinOnThePinpadReader); if(!qsReader.isEmpty()) { qsMessage += " \""; qsMessage += qsReader; qsMessage += "\""; } qsMessage += ", "; qsMessage += GETQSTRING_DLG(InOrderToAuthenticateYourself); qsMessage += "\n"; break; case DLG_PIN_SIGN: qsMessage = GETQSTRING_DLG(Caution); qsMessage += " "; qsMessage += GETQSTRING_DLG(YouAreAboutToMakeALegallyBindingElectronic); qsMessage += "\n"; qsMessage += GETQSTRING_DLG(PleaseEnterYourPinOnThePinpadReader); if(!qsReader.isEmpty()) { qsMessage += " \""; qsMessage += qsReader; qsMessage += "\""; } qsMessage += ", "; qsMessage += GETQSTRING_DLG(ToContinueOrClickTheCancelButton); qsMessage += "\n\n"; qsMessage += GETQSTRING_DLG(Warning); qsMessage += " "; qsMessage += GETQSTRING_DLG(IfYouOnlyWantToLogOnToA); qsMessage += "\n"; break; default: qsMessage = GETQSTRING_DLG(PleaseEnterYourPinOnThePinpadReader); if(!qsReader.isEmpty()) { qsMessage += " \""; qsMessage += qsReader; qsMessage += "\""; } qsMessage += "\n"; break; } break; case DLG_PIN_OP_UNBLOCK_NO_CHANGE: qsMessage = GETQSTRING_DLG(PleaseEnterYourPukOnThePinpadReader); if(!qsReader.isEmpty()) { qsMessage += " \""; qsMessage += qsReader; qsMessage += "\""; } qsMessage += ", "; qsMessage = GETQSTRING_DLG(ToUnblock); qsMessage += " "; qsMessage += GETQSTRING_DLG(Your); qsMessage += " \""; if( !qsPinName.isEmpty() ) { qsMessage += qsPinName; } else { qsMessage += GETQSTRING_DLG(Pin); } qsMessage += "\"\n"; break; case DLG_PIN_OP_CHANGE: qsMessage = GETQSTRING_DLG(ChangeYourPin); qsMessage += " \""; if( !qsPinName.isEmpty() ) { qsMessage += qsPinName; } else { qsMessage += GETQSTRING_DLG(Pin); } qsMessage += "\" "; qsMessage += GETQSTRING_DLG(OnTheReader); if(!qsReader.isEmpty()) { qsMessage += " \""; qsMessage += qsReader; qsMessage += "\""; } qsMessage += "\n"; break; case DLG_PIN_OP_UNBLOCK_CHANGE: qsMessage = GETQSTRING_DLG(ChangeYourPuk); qsMessage += " \""; if( !qsPinName.isEmpty() ) { qsMessage += qsPinName; } else { qsMessage += GETQSTRING_DLG(Pin); } qsMessage += "\" "; qsMessage += GETQSTRING_DLG(OnTheReader); if(!qsReader.isEmpty()) { qsMessage += " \""; qsMessage += qsReader; qsMessage += "\""; } qsMessage += "\n"; break; default: oInfoData->returnValue = DLG_BAD_PARAM; oShMemory.Detach((void *)oInfoData); MWLOG(LEV_ERROR, MOD_DLG, L" %s child process : Bad param", argv[0]); return 0; break; } } MWLOG(LEV_DEBUG, MOD_DLG, L" %s child process : qsMessage set", argv[0]); dlg = new QDialog(); MWLOG(LEV_DEBUG, MOD_DLG, L" %s child process : QDialog created", argv[0]); DlgPinOperation operation = oInfoData->operation; unsigned long infoCollectorIndex = oInfoData->infoCollectorIndex; // we do not need the shared memory area anymore oShMemory.Detach((void *)oInfoData); SharedMem::Delete(oShMemory.getID()); dlgInfo = new dlgWndPinpadInfo( infoCollectorIndex, operation, qsReader, PINName, qsMessage, dlg); MWLOG(LEV_DEBUG, MOD_DLG, L" %s child process : dlgWndPinpadInfo created", argv[0]); dlg->raise(); dlg->exec(); if (dlgInfo) { delete dlgInfo; dlgInfo = NULL; } if (dlg) { delete dlg; dlg = NULL; } return 0; } catch(...) { MWLOG(LEV_ERROR, MOD_DLG, L" %s child process failed", argv[0]); if (dlgInfo) { delete dlgInfo; dlgInfo = NULL; } if (dlg) { delete dlg; dlg = NULL; } oInfoData->returnValue = DLG_ERR; oShMemory.Detach((void *)oInfoData); SharedMem::Delete(oShMemory.getID()); return 0; } } return 0; } else if (iFunctionIndex == DLG_DISPLAY_MODAL) { QApplication a(argc, argv); DlgDisplayModalArguments* oData; SharedMem oShMemory; oShMemory.Attach( sizeof(DlgDisplayModalArguments), readableFilePath.c_str(),(void **) &oData); dlgWndModal *dlg = NULL; try { QString qsMesg; qsMesg=QString::fromWCharArray(oData->mesg); dlg = new dlgWndModal( oData->icon, qsMesg, oData->buttons, oData->EnterButton, oData->CancelButton ); dlg->exec(); eIDMW::DlgRet dlgResult = dlg->dlgResult; oData->returnValue = dlgResult; delete dlg; dlg = NULL; oShMemory.Detach((void *)oData); return 0; } catch( ... ) { if( dlg ) delete dlg; oData->returnValue = DLG_ERR; oShMemory.Detach((void *)oData); return 0; } oData->returnValue = DLG_CANCEL; oShMemory.Detach((void *)oData); return 0; } else if (iFunctionIndex == DLG_ASK_ACCESS) { QApplication a(argc, argv); // attach to the segment and get a pointer DlgAskAccessArguments *oData = NULL; SharedMem oShMemory; oShMemory.Attach( sizeof(DlgAskAccessArguments), readableFilePath.c_str(),(void **) &oData); dlgWndAskAccess *dlg = NULL; try { QString qsAppPath; qsAppPath=QString::fromWCharArray( oData->appPath ); QString qsReaderName; qsReaderName=QString::fromWCharArray( oData->readerName); dlg = new dlgWndAskAccess( qsAppPath, qsReaderName, oData->operation ); dlg->exec(); eIDMW::DlgRet dlgResult = dlg->dlgResult; oData->returnValue = dlgResult; if(dlg->ForAllIsChecked()) { oData->forAllOperations =1; } else { oData->forAllOperations = 0; } delete dlg; dlg = NULL; oShMemory.Detach((void *)oData); return 0; } catch( ... ) { if( dlg ) delete dlg; oData->returnValue = DLG_ERR; oShMemory.Detach((void *)oData); return 0; } oData->returnValue = DLG_ERR; oShMemory.Detach((void *)oData); return 0; } } else { // wrong number of arguments } return iRet; }
bool Wopi::setData( Item& data, const String& appName, bool atomicUpdate ) { SharedMem* pAppMem = 0; // do we have the required appname data? m_mtx.lock(); AppDataMap::const_iterator pos = m_admap.find( appName ); if( pos == m_admap.end() ) { m_mtx.unlock(); pAppMem = inner_create_appData( appName ); } else { pAppMem = pos->second; m_mtx.unlock(); } // we can deal with the shared memory in an unlocked region, of course. if ( pAppMem->currentVersion() != pAppMem->lastVersion() ) { // we already know we're out of sync. if( atomicUpdate ) inner_readData( pAppMem, data ); return false; } // ok, try and serialize the data. StringStream source; Item::e_sercode sc = data.serialize( &source, false ); if( sc != Item::sc_ok ) { throw new WopiError( ErrorParam( FALCON_ERROR_WOPI_APPDATA_SER, __LINE__ ) .desc( "Error during Serialization of application data") .extra( String("type ").N( (int) sc ) ) ); } // great, the data is serialized; try to get it out of the door. int32 datalen = (int32) source.tell(); source.seekBegin(0); bool bSuccess = pAppMem->commit( &source, datalen, atomicUpdate ); // did we succeed? if( ! bSuccess ) { // No; we wasted the serialization. However, are now required to // deserialize the item? if( atomicUpdate ) { // ... and, is there anything to be de-serialized? if( source.tell() != 0 ) { source.seekBegin(0); Item::e_sercode sc = data.deserialize( &source, VMachine::getCurrent() ); if( sc != Item::sc_ok ) { throw new WopiError( ErrorParam( FALCON_ERROR_WOPI_APPDATA_DESER, __LINE__ ) .desc( "Error during de-serialization of application data") .extra( String("type ").N( (int) sc ) ) ); } } else { data.setNil(); } } } return bSuccess; }