Beispiel #1
0
std::string NetworkSocket::debugString() const {
	if(!isOpen()) return "Closed";
	std::string ret = TypeStr(m_type) + "/" + StateStr(m_state);
	{
		std::string localStr = "INVALIDLOCAL";
		NetworkAddr addr;
		if(nlGetLocalAddr(m_socket->sock, getNLaddr(addr)) != NL_FALSE)
			NetAddrToString(addr, localStr);
		else {
			localStr = "ERRORLOCALADDR(" + GetLastErrorStr() + ")";
			ResetSocketError();
		}
		ret += " " + localStr;
	}
	if(m_state == NSS_CONNECTED) {
		ret += " connected to ";
		std::string remoteStr = "INVALIDREMOTE";
		NetworkAddr addr;
		if(nlGetRemoteAddr(m_socket->sock, getNLaddr(addr)) != NL_FALSE)
			NetAddrToString(remoteAddress(), remoteStr);
		else {
			remoteStr = "ERRORREMOTEADDR(" + GetLastErrorStr() + ")";
			ResetSocketError();
		}
		ret += remoteStr;
	}
	return ret;
}
Beispiel #2
0
bool BlakMoveFile(const char *source, const char *dest)
{
 #ifdef BLAK_PLATFORM_WINDOWS
   
   if (!CopyFile(source,dest,FALSE))
   {
      eprintf("BlakMoveFile error moving %s to %s (%s)\n",source,dest,GetLastErrorStr());
      return false;
   }
   if (!DeleteFile(source))
   {
      eprintf("BlakMoveFile error deleting %s (%s)\n",source,GetLastErrorStr());
      return false;
   }
   return true;
   
 #elif BLAK_PLATFORM_LINUX

   // Doesn't work across filesystems, but probably fine for our purposes.
   return 0 == rename(source, dest);
   
 #else
   #error No platform implementation of BlakMoveFile
 #endif
}
Beispiel #3
0
HANDLE InitPipe(HWND hDlg, char *PipeName, char *errStr)
{
	// This waits for a pipe initiation (blocks till a pipe connection or an error occurs).
	// Run this inside of a second thread.
	SECURITY_ATTRIBUTES	sa;
	SECURITY_DESCRIPTOR	sd;
	HANDLE hPipe;

	if (! InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
	{ 	strcpy (errStr, "ERROR in InitializeSecurityDescriptor()");	return NULL;	}

	if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
	{ 	strcpy (errStr, "ERROR in SetSecurityDescriptorDacl()");	return NULL;	}

	sa.nLength = sizeof(sa);			// fill sa fields;  no inheritance needed
	sa.bInheritHandle = FALSE;
	sa.lpSecurityDescriptor = &sd;
	hPipe = CreateNamedPipe( PipeName, PIPE_ACCESS_DUPLEX, 
		PIPE_TYPE_MESSAGE  | PIPE_READMODE_MESSAGE | PIPE_WAIT,
		1, _MAX_PATH +100, _MAX_PATH +100, 5000, &sa);
	
	if (hPipe == INVALID_HANDLE_VALUE)
	{	GetLastErrorStr(errStr); strcat (errStr, "  [error in CreateNamedPipe]"); return NULL;	}

	if (!WaitForController (&hPipe, errStr))
	{	GetLastErrorStr(errStr); strcat (errStr, "  [error in WaitForController]"); return NULL;	}
	
	return hPipe;
}
Beispiel #4
0
void* GetSymbol_impl(const ModuleInfo& moduleInfo, const char* symbol)
{
  HMODULE handle = nullptr;
  if (!sharedLibMode || moduleInfo.name == "main")
  {
    handle = GetModuleHandle(nullptr);
  }
  else
  {
    handle = GetModuleHandle(moduleInfo.location.c_str());
  }

  if (!handle)
  {
    US_DEBUG << "GetSymbol_impl():GetModuleHandle() " << GetLastErrorStr();
    return 0;
  }

  void* addr = (void*)GetProcAddress(handle, symbol);
  if (!addr)
  {
    US_DEBUG << "GetSymbol_impl():GetProcAddress(handle," << symbol << ") " << GetLastErrorStr();
  }
  return addr;
}
Beispiel #5
0
/*
 * DownloadCheckDirs:  Make sure that directories needed for downloading exist.
 *   hParent is parent for error dialog.
 *   Return True iff they all exist.
 */
Bool DownloadCheckDirs(HWND hParent)
{
   // Make sure that necessary subdirectories exist
   if (MakeDirectory(download_dir) == False)
   {
      ClientError(hInst, hMain, IDS_CANTMAKEDIR, download_dir, GetLastErrorStr());
      return False;
   }
   if (MakeDirectory(resource_dir) == False)
   {
      ClientError(hInst, hMain, IDS_CANTMAKEDIR, resource_dir, GetLastErrorStr());
      return False;
   }
   if (MakeDirectory(help_dir) == False)
   {
      ClientError(hInst, hMain, IDS_CANTMAKEDIR, help_dir, GetLastErrorStr());
      return False;
   }
   if (MakeDirectory(mail_dir) == False)
   {
      ClientError(hInst, hMain, IDS_CANTMAKEDIR, mail_dir, GetLastErrorStr());
      return False;
   }
   if (MakeDirectory(ad_dir) == False)
   {
      ClientError(hInst, hMain, IDS_CANTMAKEDIR, ad_dir, GetLastErrorStr());
      return False;
   }
   return True;
}
Beispiel #6
0
bool SetNetAddrPort(NetworkAddr& addr, unsigned short port, std::string* errorStr) {
	if(getNLaddr(addr) == NULL)
		return false;
	else {
		if(nlSetAddrPort(getNLaddr(addr), port) == NL_FALSE) {
			errors << "SetNetAddrPort: cannot set port " << port << ": " << GetLastErrorStr() << endl;
			if(errorStr) *errorStr = GetLastErrorStr();
			ResetSocketError();
			return false;
		}
		return true;
	}
}
void SharedLibraryHandle::Load(const std::string& name)
{
#ifdef US_BUILD_SHARED_LIBS
  if (m_Handle) throw std::logic_error(std::string("Library already loaded: ") + name);
  std::string libPath = GetAbsolutePath(name);
#ifdef US_PLATFORM_POSIX
  m_Handle = dlopen(libPath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
  if (!m_Handle)
  {
    const char* err = dlerror();
    throw std::runtime_error(err ? std::string(err) : libPath);
  }
#else
  m_Handle = LoadLibrary(libPath.c_str());
  if (!m_Handle)
  {
    std::string errMsg = "Loading ";
    errMsg.append(libPath).append("failed with error: ").append(GetLastErrorStr());

    throw std::runtime_error(errMsg);
  }
#endif

#endif

  m_Name = name;
}
Beispiel #8
0
int NetworkSocket::Read(void* buffer, int nbytes) {
	if(!isOpen()) {
		errors << "NetworkSocket::Read: cannot read on closed socket" << endl;
		return NL_INVALID;
	}

	ResetSocketError();
	NLint ret = nlRead(m_socket->sock, buffer, nbytes);
	
	// Error checking
	if (ret == NL_INVALID)  {
		// messageend-error is just that there is no data; we can ignore that
		if (!IsMessageEndSocketErrorNr(GetSocketErrorNr())) {
#ifdef DEBUG
			std::string errStr = GetLastErrorStr(); // cache errStr that debugString will not overwrite it
			errors << "ReadSocket " << debugString() << ": " << errStr << endl;
#endif
			
			// Is this perhaps the solution for the Bad file descriptor error?
			//Close();
		}
		return NL_INVALID;
	}

	return ret;
}
Beispiel #9
0
int CEchoMainWnd::PlayStim()
{
	char errbuf[256], buf[256];
	double level2, level3;
	CString NodeName, StimPathFile;

	//evaluate the signal to present
	if (!PrepareAUX())
		return 0;
	GetDlgItemText(IDC_NODELIST, NodeName);
	StimPathFile = ((NodeName == ".") ? CString(AppPath).Left(2) : "\\\\"+NodeName) + STIM_PATH_FILE;
	//signal ready. 
	if (Sig.Wavwrite(StimPathFile, buf) > 0) {
		int b;
		level = GetDlgItemDouble(hDlg, IDC_LEVEL, &b);
		if (b) {
			level2 = level - LeveldBrms(StimPathFile, &level3, buf); 
			if (PreparePresent(level2, errbuf))
				return 1;
		} else
			sprintf(errbuf, "Failed to get the level value.");
	} else {
		GetLastErrorStr(errbuf);
		sprintf(errbuf+strlen(errbuf), "Error in Wavwrite %s\n%s", StimPathFile, buf);
	}
	MessageBox(errbuf, "PlayStim");
	return 0;
}
Beispiel #10
0
// accepts "%i.%i.%i.%i[:%l]" as input
bool StringToNetAddr(const std::string& string, NetworkAddr& addr, std::string* errorStr) {
	if(getNLaddr(addr) == NULL) return false;
	
	if(!isStringValidIP(string)) {
		SetNetAddrValid(addr, false);
		return false;
	}
	
	if(nlStringToAddr(string.c_str(), getNLaddr(addr)) == NL_FALSE) {
		errors << "StringToNetAddr: cannot use " << string << " as address: " << GetLastErrorStr() << endl;
		if(errorStr) *errorStr = GetLastErrorStr();
		ResetSocketError();
		return false;
	}
	
	return true;
}
Beispiel #11
0
int WaitForController (HANDLE *hPipe, char *errStr)
{
	if (!ConnectNamedPipe(*hPipe, NULL))	
	{
		if (GetLastError() != ERROR_PIPE_CONNECTED)  
		{ GetLastErrorStr(errStr);	return 0;	}
	}
	errStr[0]=0;
	return 1;
}
Beispiel #12
0
/* this is executed in our thread, actually */
HANDLE StartAsyncNameLookup(char *peer_addr,char *buf)
{
	HANDLE ret_val;
	
	ret_val = WSAAsyncGetHostByAddr(hwndMain,WM_BLAK_SOCKET_NAME_LOOKUP,
		peer_addr,4,PF_INET,buf,MAXGETHOSTSTRUCT);
	if (ret_val == 0)
		eprintf("StartAsyncNameLookup got error %s\n",GetLastErrorStr());
	
	return ret_val;
}
Beispiel #13
0
void StartAsyncSession(session_node *s)
{
	//epoll_event *ee = (epoll_event *) AllocateMemory(MALLOC_ID_NETWORK, sizeof(epoll_event));
	epoll_event ee;
	ee.events = EPOLLIN | EPOLLOUT | EPOLLET;
	ee.data.fd = s->conn.socket;
	if (epoll_ctl(fd_epoll,EPOLL_CTL_ADD,s->conn.socket,&ee) != 0)
	{
	    eprintf("StartAsyncSession error adding socket %s\n",GetLastErrorStr());
		return;
    }
}
Beispiel #14
0
std::string GetLibraryPath_impl(void *symbol)
{
  HMODULE handle = 0;
  BOOL handleError = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                                       static_cast<LPCTSTR>(symbol), &handle);
  if (!handleError)
  {
    // Test
    US_DEBUG << "GetLibraryPath_impl():GetModuleHandle() " << GetLastErrorStr();
    return "";
  }

  char modulePath[512];
  if (GetModuleFileName(handle, modulePath, 512))
  {
    return modulePath;
  }

  US_DEBUG << "GetLibraryPath_impl():GetModuleFileName() " << GetLastErrorStr();
  return "";
}
Beispiel #15
0
void StartAsyncSocketAccept(SOCKET sock,int connection_type)
{
	//epoll_event *ee = (epoll_event *) AllocateMemory(MALLOC_ID_NETWORK, sizeof(epoll_event));
	epoll_event ee;
	ee.events = EPOLLIN;
	ee.data.fd = sock;
	if (epoll_ctl(fd_epoll,EPOLL_CTL_ADD,sock,&ee) != 0)
	{
	    eprintf("StartAsyncSocketAccept error adding socket %s\n",GetLastErrorStr());
		return;
    }

	accept_sockets.push_back(std::make_pair(sock, connection_type));
}
Beispiel #16
0
void pipeThread (PVOID nsr)
{
	CStdString parsedMsg[MAX_WORDS_PIPEMSG];
	char *pipeNameStr = (char *)nsr;
	DWORD dw, ecode;
	HANDLE hPipe;
	int res, nArg;
	char PipeName[256], buffer[MAX_PATH], errstr[MAX_PATH], inBuf[MAX_PATH*4], inBuf2[MAX_PATH*4];
	HWND hDlg = hMainDlg;

	wsprintf(PipeName, "\\\\.\\pipe\\%s", pipeNameStr);

	if ((hPipe=InitPipe(hDlg, PipeName, errstr))==NULL)
	{ MessageBox (hDlg, errstr, "pipeThread", MB_OK);		_endthread();		return;	}

	_beginthread (pipeThread, 0, (void*)ACEPLAYER_CONSOLE_PIPENAME);

	while (1)
	{
		if (!ConnectNamedPipe (hPipe, NULL))
		{
			if (GetLastError() != ERROR_PIPE_CONNECTED)
			{	GetLastErrorStr(errstr);
				MessageBox (hDlg, "ERROR in ConnectNamedPipe()", errstr, MB_OK);
				_endthread();				return;			}
		}
		res = ReadFile (hPipe, inBuf, sizeof(inBuf), &dw, NULL);	inBuf[dw]='\0';
		if (!res)
		{
			 
			if ((ecode=GetLastError())==234)  /*More data is available.*/
			{
				ReadFile (hPipe, inBuf2, sizeof(inBuf), &dw, NULL);
				strcat(inBuf, inBuf2);
			}
			else
			{
				sprintf(buffer, "Erorr code=%d", ecode);
				MessageBox (hDlg, "ReadFile fails for pipe communication", buffer, MB_OK);
				break;
			}
		}
		nArg = str2array (parsedMsg, MAX_WORDS_PIPEMSG, inBuf, " ");
		SendMessage (GetDlgItem(hMainDlg, IDC_STATUSBAR), SB_SETTEXT, 1, (LPARAM)inBuf);
		EditPrintf (GetDlgItem(hPipeLog, IDC_MSG), "(incoming) %s\r\n", inBuf);
		ProcessParsedString (hPipe, parsedMsg, nArg);
		DisconnectNamedPipe(hPipe); // For Stateless named pipe connection, turn this line on.
		FlushFileBuffers(hPipe);
	}
}
Beispiel #17
0
bool NetworkSocket::Listen() {
	if(!isOpen()) {
		errors << "NetworkSocket::Listen: socket is closed" << endl;
		return false;
	}
	
	if(nlListen(m_socket->sock) == NL_FALSE) {
#ifdef DEBUG
		errors << "Listen: " << GetLastErrorStr() << endl;
#endif
		ResetSocketError();
		return false;
	}
	
	checkEventHandling();
	return true;
}
Beispiel #18
0
bool NetworkSocket::OpenBroadcast(Port port) {
	if(isOpen()) {
		warnings << "NetworkSocket " << debugString() << ": OpenBroadcast: socket is already opened, reopening now" << endl;
		Close();
	}

	NLsocket ret = nlOpen(port, NL_BROADCAST);
	if (ret == NL_INVALID)  {
#ifdef DEBUG
		errors << "OpenBroadcastSocket: " << GetLastErrorStr() << endl;
#endif
		ResetSocketError();
		return false;
	}
	m_socket->sock = ret;
	m_type = NST_UDPBROADCAST;
	m_state = NSS_NONE;
	checkEventHandling();
	return true;	
}
Beispiel #19
0
bool NetworkSocket::Connect(const NetworkAddr& addr) {
	if(!isOpen()) {
		errors << "NetworkSocket::Connect: socket is closed" << endl;
		return false;
	}
	
	if(m_type != NST_TCP) {
		errors << "NetworkSocket::Connect " << debugString() << ": connect only works with TCP" << endl;
		return false;
	}
	
	if(nlConnect(m_socket->sock, getNLaddr(addr)) == NL_FALSE) {
#ifdef DEBUG
		errors << "Connect: " << GetLastErrorStr() << endl;
#endif
		ResetSocketError();
		return false;
	}
	
	checkEventHandling();
	return true;
}
Beispiel #20
0
int NetworkSocket::Write(const void* buffer, int nbytes) {
	if(!isOpen()) {
		errors << "NetworkSocket::Write: cannot write on closed socket" << endl;
		return NL_INVALID;
	}
	
	ResetSocketError();
	NLint ret = nlWrite(m_socket->sock, buffer, nbytes);

	// Error checking
	if (ret == NL_INVALID)  {
#ifdef DEBUG
		std::string errStr = GetLastErrorStr(); // cache errStr that debugString will not overwrite it
		errors << "WriteSocket " << debugString() << ": " << errStr << endl;
#endif // DEBUG
		return NL_INVALID;
	}

	/*if (ret == 0) {  // HINT: this is not an error, it is one of the ways to find out if a socket is writeable
		errors << "WriteSocket: Could not send the packet, network buffers are full." << endl;
	}*/

	return ret;
}
Beispiel #21
0
bool WaitCondition::Wait(MutexType& mutex, unsigned long timeoutMillis)
{
  #ifdef US_PLATFORM_POSIX
    struct timespec ts, * pts = 0;
    if (timeoutMillis)
    {
      pts = &ts;
      struct timeval tv;
      int error = gettimeofday(&tv, NULL);
      if (error)
      {
        US_ERROR << "gettimeofday error: " << GetLastErrorStr();
        return false;
      }
      ts.tv_sec = tv.tv_sec;
      ts.tv_nsec = tv.tv_usec * 1000;
      ts.tv_sec += timeoutMillis / 1000;
      ts.tv_nsec += (timeoutMillis % 1000) * 1000000;
      ts.tv_sec += ts.tv_nsec / 1000000000;
      ts.tv_nsec = ts.tv_nsec % 1000000000;
    }

    if (pts)
    {
      int error = pthread_cond_timedwait(&m_WaitCondition, &mutex.m_Mtx, pts);
      if (error == 0)
      {
        return true;
      }
      else
      {
        if (error != ETIMEDOUT)
        {
          US_ERROR << "pthread_cond_timedwait error: " << GetLastErrorStr();
        }
        return false;
      }
    }
    else
    {
      int error = pthread_cond_wait(&m_WaitCondition, &mutex.m_Mtx);
      if (error)
      {
        US_ERROR << "pthread_cond_wait error: " << GetLastErrorStr();
        return false;
      }
      return true;
    }

  #else

    // Avoid race conditions
    EnterCriticalSection(&m_NumberOfWaitersLock);
    m_NumberOfWaiters++;
    LeaveCriticalSection(&m_NumberOfWaitersLock);

    DWORD dw;
    bool result = true;

    // This call atomically releases the mutex and waits on the
    // semaphore until signaled
    dw = SignalObjectAndWait(mutex.m_Mtx, m_Semaphore, timeoutMillis ? timeoutMillis : INFINITE, FALSE);
    if (dw == WAIT_TIMEOUT)
    {
      result = false;
    }
    else if (dw == WAIT_FAILED)
    {
      result = false;
      US_ERROR << "SignalObjectAndWait failed: " << GetLastErrorStr();
    }

    // Reacquire lock to avoid race conditions
    EnterCriticalSection(&m_NumberOfWaitersLock);

    // We're no longer waiting....
    m_NumberOfWaiters--;

    // Check to see if we're the last waiter after the broadcast
    int lastWaiter = m_WasNotifyAll && m_NumberOfWaiters == 0;

    LeaveCriticalSection(&m_NumberOfWaitersLock);

    // If we're the last waiter thread during this particular broadcast
    // then let the other threads proceed
    if (lastWaiter)
    {
      // This call atomically signals the m_WaitersAreDone event and waits
      // until it can acquire the external mutex.  This is required to
      // ensure fairness
      dw = SignalObjectAndWait(m_WaitersAreDone, mutex.m_Mtx,
                          INFINITE, FALSE);
      if (result && dw == WAIT_FAILED)
      {
        result = false;
        US_ERROR << "SignalObjectAndWait failed: " << GetLastErrorStr();
      }
    }
    else
    {
      // Always regain the external mutex since that's the guarentee we
      // give to our callers
      dw = WaitForSingleObject(mutex.m_Mtx, INFINITE);
      if (result && dw == WAIT_FAILED)
      {
        result = false;
        US_ERROR << "SignalObjectAndWait failed: " << GetLastErrorStr();
      }
    }

    return result;
  #endif
}
Beispiel #22
0
/*
 * TransferStart: Retrieve files; the information needed to set up the
 * transfer is in info.
 *
 * This function is run in its own thread.
 */
void __cdecl TransferStart(void *download_info)
{
    Bool done;
    char filename[MAX_PATH + FILENAME_MAX];
    char local_filename[MAX_PATH + 1];  // Local filename of current downloaded file
    int i;
    int outfile;                   // Handle to output file
    DWORD size;                      // Size of block we're reading
    int bytes_read;                // Total # of bytes we've read

#if defined VANILLA_UPDATER
    const char *mime_types[2] = { "application/x-zip-compressed" };
#else
    const char *mime_types[4] = { "application/octet-stream", "text/plain", "application/x-msdownload", NULL };
    //const char *mime_types[2] = { "application/octet-stream", NULL };
#endif

    DWORD file_size;
    DWORD file_size_buf_len;
    DWORD index = 0;
    DownloadInfo *info = (DownloadInfo *)download_info;

    aborted = False;
    hConnection = NULL;
    hSession = NULL;
    hFile = NULL;

    hConnection = InternetOpen(szAppName, INTERNET_OPEN_TYPE_PRECONFIG,
                               NULL, NULL, INTERNET_FLAG_RELOAD);

    if (hConnection == NULL)
    {
        DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTINIT));
        return;
    }

    if (aborted)
    {
        TransferCloseHandles();
        return;
    }

    hSession = InternetConnect(hConnection, info->machine, INTERNET_INVALID_PORT_NUMBER,
                               NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if (hSession == NULL)
    {
        DownloadError(info->hPostWnd, GetString(hInst, IDS_NOCONNECTION), info->machine);
        return;
    }

    for (i = info->current_file; i < info->num_files; i++)
    {
        if (aborted)
        {
            TransferCloseHandles();
            return;
        }

        // Skip non-guest files if we're a guest
        if (config.guest && !(info->files[i].flags & DF_GUEST))
        {
            PostMessage(info->hPostWnd, BK_FILEDONE, 0, i);
            continue;
        }

        // If not supposed to transfer file, inform main thread
        if (DownloadCommand(info->files[i].flags) != DF_RETRIEVE)
        {
            // Wait for main thread to finish processing previous file
            WaitForSingleObject(hSemaphore, INFINITE);

            if (aborted)
            {
                TransferCloseHandles();
                return;
            }

            PostMessage(info->hPostWnd, BK_FILEDONE, 0, i);
            continue;
        }
#if VANILLA_UPDATER
        sprintf(filename, "%s%s", info->path, info->files[i].filename);
#else
        sprintf(filename, "%s//%s", info->path, info->files[i].filename);
#endif
        hFile = HttpOpenRequest(hSession, NULL, filename, NULL, NULL,
                                mime_types, INTERNET_FLAG_NO_UI, 0);
        if (hFile == NULL)
        {
            debug(("HTTPOpenRequest failed, error = %d, %s\n",
                   GetLastError(), GetLastErrorStr()));
            DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTFINDFILE),
                          filename, info->machine);
            return;
        }

        if (!HttpSendRequest(hFile, NULL, 0, NULL, 0)) {
            debug(("HTTPSendRequest failed, error = %d, %s\n",
                   GetLastError(), GetLastErrorStr()));
            DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTSENDREQUEST),
                          filename, info->machine);
            return;
        }

        // Get file size
        file_size_buf_len = sizeof(file_size);
        index = 0;
        if (!HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
                           &file_size, &file_size_buf_len, &index)) {
            debug(("HTTPQueryInfo failed, error = %d, %s\n",
                   GetLastError(), GetLastErrorStr()));
            DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTGETFILESIZE),
                          filename, info->machine);
            return;
        }

        PostMessage(info->hPostWnd, BK_FILESIZE, i, file_size);
#if VANILLA_UPDATER
        sprintf(local_filename, "%s\\%s", download_dir, info->files[i].filename);
#else
        sprintf(local_filename, "%s\\%s", info->files[i].path, info->files[i].filename);
#endif
        outfile = open(local_filename, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, S_IWRITE | S_IREAD);
        if (outfile <= 0)
        {
            debug(("Couldn't open local file %s for writing\n", local_filename));
            DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTWRITELOCALFILE),
                          local_filename);
            return;
        }

        // Read first block
        done = False;
        bytes_read = 0;
        while (!done)
        {
            if (!InternetReadFile(hFile, buf, BUFSIZE, &size))
            {
                DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTREADFTPFILE), filename);
            }

            if (size > 0)
            {
                if (write(outfile, buf, size) != size)
                {
                    DownloadError(info->hPostWnd, GetString(hInst, IDS_CANTWRITELOCALFILE),
                                  local_filename);
                    close(outfile);
                    return;
                }
            }

            // Update graph position
            bytes_read += size;
            PostMessage(info->hPostWnd, BK_PROGRESS, 0, bytes_read);

            // See if done with file
            if (size == 0)
            {
                close(outfile);
                InternetCloseHandle(hFile);
                done = True;

                // Wait for main thread to finish processing previous file
                WaitForSingleObject(hSemaphore, INFINITE);

                if (aborted)
                {
                    TransferCloseHandles();
                    return;
                }

                PostMessage(info->hPostWnd, BK_FILEDONE, 0, i);
            }
        }
    }

    InternetCloseHandle(hSession);
    InternetCloseHandle(hConnection);

    PostMessage(info->hPostWnd, BK_TRANSFERDONE, 0, 0);
}
Beispiel #23
0
NetworkAddr NetworkSocket::remoteAddress() const {
	NetworkAddr addr;
	
	if(!isOpen()) {
		errors << "NetworkSocket::remoteAddress: socket is closed" << endl;
		return addr;
	}
	
	if(nlGetRemoteAddr(m_socket->sock, getNLaddr(addr)) == NL_FALSE) {
		errors << "NetworkSocket::remoteAddress: cannot get remote address" << "(" << debugString() << "): " << GetLastErrorStr() << endl;
		ResetSocketError();
		return addr;
	}
	
	return addr;
}
Beispiel #24
0
bool NetworkSocket::setRemoteAddress(const NetworkAddr& addr) {
	if(!isOpen()) {
		errors << "NetworkSocket::setRemoteAddress: socket is closed" << endl;
		return false;
	}
	
	if(getNLaddr(addr) == NULL) {
		errors << "NetworkSocket::setRemoteAddress " << debugString() << ": given address is invalid" << endl;
		return false;
	}
	if( GetNetAddrPort(addr) == 0 )
	{
		errors << "NetworkSocket::setRemoteAddress " << debugString() << ": port is set to 0" << endl;
	}
	
	if(nlSetRemoteAddr(m_socket->sock, getNLaddr(addr)) == NL_FALSE) {
		std::string addrStr = "INVALIDADDR";
		NetAddrToString(addr, addrStr);
		errors << "NetworkSocket::setRemoteAddress " << debugString() << ": failed to set destination " << addrStr << ": " << GetLastErrorStr() << endl;
		ResetSocketError();
		return false;
	}
	
	return true;
}
Beispiel #25
0
void aux_HOOK(CAstSig &ast, const AstNode *pnode, const AstNode *p)
{
	string HookName;
	const AstNode *args;
	if (pnode->str[0] == '#') {
		HookName = pnode->str+1;
		args = p;
	} else {
		const char *fnsigs[] = {
			"(name_string, ...)", 0};
		HookName = ast.ComputeString(p);
		checkNumArgs(pnode, p, fnsigs, 1, 0);
		args = p->next;
	}

	CSignals first;
	char buf[512];

	if (ast.CallbackHook && ast.CallbackHook(ast, pnode, p)==0)
		;
	else if (HookName == "PLAY") {
		const char *fnsigs[] = {
			"(signal [, async_flag])",
			"(\"stop\", handle_scalar)", 0};
		checkNumArgs(pnode, args, fnsigs, 1, 2);
		first = ast.Compute(args);
		unsigned long second = 0;
		if (args->next) {
			ast.Compute(args->next);
			if (!ast.Sig.IsScalar())
				throw CAstException(pnode, args->next, fnsigs, "argument must be a scalar.");
			second = (unsigned long)(ast.Sig.value()+(ast.Sig.value()<0?-.5:.5));
		}
		int flag = 0;	
		if (first.IsString()) {
			string cmd = first.string();
			std::transform(cmd.begin(), cmd.end(), cmd.begin(), ::tolower);
			void *pvoid = (void *)second;
			if (cmd == "stop")
				TerminatePlay(pvoid);
			else if (cmd == "pause")
				PauseResumePlay(pvoid, 0);
			else if (cmd == "resume")
				PauseResumePlay(pvoid, 1);
			else
				throw CAstException(args, "Unknown command in the string -", cmd);
			return;
		}
		char *errstr = buf;
		// second == 0:Synchronous, 1:Asynchronous, 2:Loop
		void *res = first.PlayArray(0, (second==0)?0:WM_USER+293, NULL, (second==2)?-1:0, errstr);
		if (!res)
			throw CAstException(pnode, "PlayArray() failed:", errstr);
		ast.Sig.SetValue((double)(unsigned long)res);
	} else if (HookName == "INPUT") {
		const char *fnsigs[] = {
			"(message_string [, title_string])", 0};
		checkNumArgs(pnode, args, fnsigs, 1, 2);
		string msg, title;
		msg = ast.ComputeString(args);
		if (args->next)
			title = ast.ComputeString(args->next);
		else {
			ostringstream caption;
			caption << "Line " << pnode->line;
			title = caption.str();
		}
		buf[0] = '\0';
		InputBox(title.c_str(), msg.c_str(), buf, sizeof(buf));
		ast.Sig.UpdateBuffer((int)strlen(buf));
		for (int i=0; buf[i]; ++i)
			ast.Sig.buf[i] = buf[i];
	} else if (HookName == "PIPE") {
		const char *fnsigs[] = {
			"(message_string [, node_name_string [, pipe_name_string]])", 0};
		checkNumArgs(pnode, args, fnsigs, 1, 3);
#define SIGNAL_INTERFACE_PIPENAME  "CochlearAudioSignalInterfacePipe"
		string pipemsg = ast.ComputeString(args);
		string nodename = ".";
		string pipename = SIGNAL_INTERFACE_PIPENAME;
		if (args->next) {
			nodename = ast.ComputeString(args->next);
			if (args->next->next)
				pipename = ast.ComputeString(args->next->next);
		}
		pipename = "\\\\" + nodename + "\\pipe\\" + pipename;
		char reply[50000] = "";
		unsigned long nRead;
		if (!CallNamedPipe(pipename.c_str(), (LPVOID)pipemsg.c_str(), (DWORD)pipemsg.size()+1, reply, (DWORD)sizeof(reply), &nRead, NMPWAIT_WAIT_FOREVER)) {
			char *errstr = buf;
			GetLastErrorStr(errstr);
			throw CAstException(pnode, "CallNamedPipe(" + pipename + ") failed:", errstr);
		}
		reply[nRead]='\0';
		ast.Sig.UpdateBuffer((int)nRead);
		for (int i=0; reply[i]; ++i)
			ast.Sig.buf[i] = reply[i];
	} else if (HookName == "ELAPSE") {
		const char *fnsigs[] = {
			"( )", 0};
		checkNumArgs(pnode, args, fnsigs, 0, 0);
		ast.Sig.SetValue(GetTickCount() - ast.Tick0);
	} else if (HookName == "SLEEP") {
		const char *fnsigs[] = {
			"(millisecond)", 0};
		checkNumArgs(pnode, args, fnsigs, 1, 1);
		ast.Compute(args);
		if (!ast.Sig.IsScalar())
			throw CAstException(pnode, args, fnsigs, "argument must be a scalar.");
		int n = round(ast.Sig.value());
		Sleep(n);
	} else
		throw CAstException(pnode, "Undefined HOOK name:", HookName);
};
Beispiel #26
0
std::string GetSocketErrorStr(int errnr) {
	return GetLastErrorStr();
}
Beispiel #27
0
int CEchoMainWnd::PreparePresent(double level2, char *errstr)
{
	char reply[512], PipeName[128], command[376];
	CString NodeName, StimPathFile;
	string strbuffer[2];
	int res, nItems;
	DWORD nRead;
	reply[0]=0;
	GetDlgItemText(IDC_NODELIST, NodeName);
	sprintf(PipeName, "\\\\%s\\pipe\\%s", NodeName, INTERFACE_PIPENAME);
	StimPathFile = ((NodeName == ".") ? CString(AppPath).Left(2) : "\\\\"+NodeName) + STIM_PATH_FILE;
	sprintf (command, "PREPARE %5.1f %s", level2, StimPathFile);
	DISP_PIPE_LOG("[out]",command);
	// temporary code for a secondary presenter. 9/1/2010 jhpark
		char PipeName2[128];
		sprintf(PipeName2, "\\\\%s\\pipe\\%s2", NodeName, INTERFACE_PIPENAME);
		res = CallNamedPipe(PipeName2, (LPVOID)(LPCTSTR)command, (DWORD)strlen(command)+1,
			preparedCondition, MAX_PROCESSING_CONDITION_STRING, &nRead, NMPWAIT_WAIT_FOREVER);
	// end temporary code
	res = CallNamedPipe(PipeName, (LPVOID)(LPCTSTR)command, (DWORD)strlen(command)+1,
		preparedCondition, MAX_PROCESSING_CONDITION_STRING, &nRead, NMPWAIT_WAIT_FOREVER);
	while (!res)
	{
		GetLastErrorStr(reply);
		sprintf (errstr, "Error in CallNamedPipe (PREPARE)\nmsg: %s", reply);
		if (MessageBox (errstr, "Retry or cancel? (you can still retry after changing settings)", MB_RETRYCANCEL)==IDRETRY)
			res = CallNamedPipe(PipeName, (LPVOID)(LPCTSTR)command, (DWORD)strlen(command)+1,
					preparedCondition, MAX_PROCESSING_CONDITION_STRING, &nRead, NMPWAIT_WAIT_FOREVER);
		else
			return 0;
	}
	preparedCondition[nRead]='\0';
	DISP_PIPE_LOG("[in]",preparedCondition);	
	nItems=str2array(strbuffer, 2, preparedCondition, " ");
	if (nItems>0 && strbuffer[0] =="SUCCESS") {
		if (nItems==1)
			preparedCondition[0] = '\0';
		else
			memmove(preparedCondition, preparedCondition+8, nRead-7);
	} else {		
		sprintf (errstr, "FAILURE during PREPARE --> %s", preparedCondition);
		return 0;
	}

	strcpy(command, "PRESENT");
	DISP_PIPE_LOG("[out]",command);
	// temporary code for a secondary presenter. 9/1/2010 jhpark
		res = CallNamedPipe(PipeName2, (LPVOID)(LPCTSTR)command, (DWORD)strlen(command)+1,
			preparedCondition, MAX_PROCESSING_CONDITION_STRING, &nRead, NMPWAIT_WAIT_FOREVER);
	// end temporary code
	res = CallNamedPipe(PipeName, (LPVOID)(LPCTSTR)command, (DWORD)strlen(command)+1,
		reply, sizeof(reply), &nRead, NMPWAIT_WAIT_FOREVER); 
	while (!res)
	{
		GetLastErrorStr(errstr);
		if(MessageBox ("CallNamedPipe failed(PRESENT). Retry(Yes), or Abort(No)?", errstr, MB_YESNO)==IDYES)
		{
			res = CallNamedPipe(PipeName, (LPVOID)(LPCTSTR)command, (DWORD)strlen(command)+1,
				reply, sizeof(reply), &nRead, NMPWAIT_WAIT_FOREVER);
		}
		else
		{
			return 0;
		}
	}
	reply[nRead]='\0';
	DISP_PIPE_LOG("[in]",reply);
	nItems=str2array(strbuffer, 2, reply, " ");
	if (nItems>0 && strbuffer[0] =="SUCCESS") {
		if (SendDlgItemMessage (IDC_ACOUSTIC, BM_GETCHECK)==BST_CHECKED) {
			CSignals x(StimPathFile);
			if (!x.PlayArray(errstr)) {
				sprintf(reply, "Playarray error: %s", errstr);
				MessageBox (reply);
			}
		}
	} else {		
		sprintf (errstr, "FAILURE during PRESENT --> %s", reply);
		return 0;
	}
	return 1;
}
Beispiel #28
0
void CloseSession(int session_id)
{
	session_node *s;
	
	s = GetSessionByID(session_id);
	if (s == NULL)
	{
		eprintf("CloseSession can't find session %i\n",session_id);
		return;
	}
	
	if (!s->connected)
	{
		eprintf("CloseSession can't close unconnected session %i\n",
			s->session_id);
		return;
	}
	
	EnterSessionLock();
	
	s->connected = False;
	
	if (!s->exiting_state)	/* if a write error occurred during an exit, don't */
		ExitSessionState(s);	/* go into infinite loop */
	
	if ((s->state != STATE_MAINTENANCE) && (s->account == NULL))
		lprintf("CloseSession closing session with no account from %s\n",
		s->conn.name);
	else
	{
		AccountLogoff(s->account);
		if (s->account != NULL)
			lprintf("CloseSession/4 logging off %i\n",s->account->account_id);
	}
	
	s->account = NULL;
	
	InterfaceLogoff(s);
	
	if (s->conn.type == CONN_SOCKET)
	{
		if (WaitForSingleObject(s->muxSend,10000) != WAIT_OBJECT_0)
			eprintf("CloseSession couldn't get session %i muxSend\n",s->session_id);
		else
		{
			DeleteBufferList(s->send_list);
			s->send_list = NULL;
			
			/* no need to release mutex... we're closing it */
			/*
			if (!ReleaseMutex(s->muxSend))
			eprintf("File %s line %i release of non-owned mutex\n",__FILE__,__LINE__);
			*/
			
		}
		
		if (WaitForSingleObject(s->muxReceive,10000) != WAIT_OBJECT_0)
			eprintf("CloseSession couldn't get session %i muxReceive\n",s->session_id);
		else
		{
			DeleteBufferList(s->receive_list);
			s->receive_list = NULL;
			
			/* no need to release mutex... we're closing it */
			/*
			if (!ReleaseMutex(s->muxReceive))
			eprintf("File %s line %i release of non-owned mutex\n",__FILE__,__LINE__);
			*/
			
		}
		
		if (!CloseHandle(s->muxSend))
			eprintf("CloseSession error (%s) closing send mutex %i in session %i\n",
			GetLastErrorStr(),s->muxSend,s->session_id);
		
		if (!CloseHandle(s->muxReceive))
			eprintf("CloseSession error (%s) closing receive mutex %i in session %i\n",
			GetLastErrorStr(),s->muxReceive,s->session_id);
		
		CloseConnection(s->conn);
	}
	
	s->session_id = -1;
	s->state = -1;
	
	LeaveSessionLock();
}
Beispiel #29
0
void RunMainLoop(void)
{
   INT64 ms;
   const uint32_t num_notify_events = 500;
   struct epoll_event notify_events[num_notify_events];
   int i;

   signal(SIGPIPE, SIG_IGN);

   while (!GetQuit())
   {
	   ms = GetMainLoopWaitTime();

	   // wait up to ms, dispatch any socket events
	   int val = epoll_wait(fd_epoll, notify_events, num_notify_events, ms);
	   if (val == -1)
	   {
		   eprintf("RunMainLoop error on epoll_wait %s\n", GetLastErrorStr());
	   }
	   //printf("got events %i %lu\n", val, ms);
	   for (i=0;i<val;i++)
	   {
		   if (notify_events[i].events == 0)
			   continue;

		   if (IsAcceptingSocket(notify_events[i].data.fd))
		   {
			   if (notify_events[i].events & ~EPOLLIN)
			   {
				   eprintf("RunMainLoop error on accepting socket %i\n",notify_events[i].data.fd);
			   }
			   else
			   {
				   AsyncSocketAccept(notify_events[i].data.fd,FD_ACCEPT,0,GetAcceptingSocketConnectionType(notify_events[i].data.fd));
			   }
		   }
		   else
		   {
			   if (notify_events[i].events & ~(EPOLLIN | EPOLLOUT))
			   {
				   // this means there was an error
				   AsyncSocketSelect(notify_events[i].data.fd,0,1);
			   }
			   else
			   {
				   if (notify_events[i].events & EPOLLIN)
				   {
					   AsyncSocketSelect(notify_events[i].data.fd,FD_READ,0);
				   }
				   if (notify_events[i].events & EPOLLOUT)
				   {
					   AsyncSocketSelect(notify_events[i].data.fd,FD_WRITE,0);
				   }
			   }
		   }

	   }
	   EnterServerLock();
	   PollSessions(); /* really just need to check session timers */
	   TimerActivate();
	   LeaveServerLock();
   }

   close(fd_epoll);
}
Beispiel #30
0
void CPlotDlg::OnMenu(UINT nID)
{
	static char fullfname[MAX_PATH];
	static CAxis *axSpec(NULL);
	CAxis *localax(gcf->ax[0]); // Following the convention
	CRect rt;
	CSize sz;
	CFont editFont;
	CPosition pos;
	double range, miin(1.e15), maax(-1.e15);
	double width, newmin, newmax;
	int i, len, id1, id2, iSel(-1);
	char errstr[256];
	CSignals signal;
	bool multi;
	static void  *playPoint;
	switch (nID)
	{
	case IDM_FULLVIEW:
		localax->setRange('x',localax->m_ln[0]->xdata[0], localax->m_ln[0]->xdata[localax->m_ln[0]->len-1]);
		localax->setTick('x', 0, localax->m_ln[0]->xdata[localax->m_ln[0]->len-1]/10, 1, 0, "%6.3f");
		// 2/3/2011, commented out by jhpark, because y axis is not affected by zooming.
		//localax->setRange('y', -1, 1);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;

	case IDM_ZOOM_IN:
		width = localax->xlim[1] - localax->xlim[0];
		if (width<0.005) return;
		localax->setRange('x', localax->xlim[0] + width/4., localax->xlim[1] - width/4.);
		width = localax->xtick.a2 - localax->xtick.a1;
		localax->xtick.a2 -= width/4.;
		localax->xtick.a1 += width/4.;
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;

	case IDM_ZOOM_OUT:
		if (localax->xlim[1]==localax->xlimFull[1] && localax->xlim[0]==localax->xlimFull[0]) return;
		for (i=0; i<localax->nLines; i++)
			miin = min(miin, getMin(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		for (i=0; i<localax->nLines; i++)
			maax = max(maax, getMax(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		width = localax->xlim[1] - localax->xlim[0];
		localax->setRange('x', max(miin,localax->xlim[0] - width/2.), min(maax,localax->xlim[1] + width/2.));
		width = localax->xtick.a2 - localax->xtick.a1;
		//Oh, I just realized that a1 and a2 do not need to be within the range==> no need to check, it will still draw the ticks only within the range.
		localax->xtick.a2 += width/2.;
		localax->xtick.a1 -= width/2.;
		if (localax->xtick.a1<0) localax->xtick.a1=0;
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_SCROLL_LEFT:
		for (i=0; i<localax->nLines; i++)
			miin = min(miin, getMin(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmin = max(miin, localax->xlim[0]-range);
		localax->setRange('x', newmin, newmin+range);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_SCROLL_RIGHT:
		for (i=0; i<localax->nLines; i++)
			maax = max(maax, getMax(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmax = min(maax, localax->xlim[1]+range);
		localax->setRange('x', newmax-range, newmax);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_LEFT_STEP:
		for (i=0; i<localax->nLines; i++)
			miin = min(miin, getMin(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmin = max(miin, localax->xlim[0]-range/4.);
		localax->setRange('x', newmin, newmin+range);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_RIGHT_STEP:
		for (i=0; i<localax->nLines; i++)
			maax = max(maax, getMax(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmax = min(maax, localax->xlim[1]+range/4.);
		localax->setRange('x', newmax-range, newmax);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_PLAY:
		errstr[0]=0;
		if (!playing)
			if(!GetSignalInRange(signal,1))		MessageBox (errStr);
			else 
			{
				playPoint = signal.PlayArray(devID, WM__SOUND_EVENT, hDlg, &block, errstr);
				playing = true;
			}
		else
		{
			PauseResumePlay(playPoint, paused);
			playing = paused;
			if (paused) paused = false;
		}
		return;
	case IDM_PAUSE:
		errstr[0]=0;
		if (playing)
		{
			PauseResumePlay(playPoint, false);
			paused = true;
		}
		return;
	case IDM_SPECTRUM:
		// To draw a spectrum, first re-adjust the aspect ratio of the client window 
		// so that the width is at least 1.5 times the height.
		if (!specView)
		{
			GetWindowRect(&rt);
			sz = rt.Size();
			if (sz.cx<3*sz.cy/2)
			{
				rt.InflateRect(0, 0, 3*sz.cy/2, 0);
				MoveWindow(&rt, 0);
			}
			//Again, //Assuming that the first axis is the waveform viewer, the second one is for spectrum viewing
			lastPos = gcf->ax[0]->pos;
			gcf->ax[0]->setPos(.08, .1, .62, .8);
			axSpec = gcf->axes(.75, .3, .22, .4);
			axSpec->colorBack = RGB(230, 230, 190);
			OnMenu(IDM_SPECTRUM_INTERNAL);
		}
		else
		{
			deleteObj(axSpec);
			axSpec=NULL;
			gcf->ax[0]->setPos(lastPos);
		}
		specView = !specView;
		break;
	case IDM_SPECTRUM_INTERNAL:
		rfftw_plan plan;
		double *freq, *fft, *mag, *fft2, *mag2, fs, maxx, maxmag, ylim;
		multi = localax->nLines>1 ? true : false;
		if (gcf->nAxes==1) break;
		fs = (double)sig.GetFs();
		for (; gcf->ax[1]->nLines>0;)	
			deleteObj(gcf->ax[1]->m_ln[0]);
		GetIndicesInRange(localax, id1, id2);
		len = id2-id1+1;
		freq = new double[len];
		fft = new double[len];
		mag = new double[len/2];
		for (i=0; i<len; i++)
			freq[i]=(double)i/(double)len*fs;
		plan = rfftw_create_plan(len, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_OUT_OF_PLACE);
		rfftw_one(plan, &localax->m_ln[0]->ydata[id1], fft);
		if (multi) 
		{
			fft2 = new double[len];
			mag2 = new double[len/2];
			rfftw_one(plan, &localax->m_ln[1]->ydata[id1], fft2);
		}
		rfftw_destroy_plan(plan);
		for (i=0; i<len/2; i++)		mag[i] = 20.*log10(fabs(fft[len-i]));
		if (multi) for (i=0; i<len/2; i++)	mag2[i] = 20.*log10(fabs(fft2[len-i]));
		maxmag = getMax(len/2,mag);
		maxx = 5.*(maxmag/5.+1);
		for (int j=0; j<len/2; j++)	mag[j] -= maxx;
		if (multi) 
		{
			maxmag = getMax(len/2,mag2);
			maxx = 5.*(maxmag/5.+1);
			for (int j=0; j<len/2; j++)	mag2[j] -= maxx;
		}
		ylim = 10.*(maxmag/10.+1)-maxx;
		PlotDouble(gcf->ax[1], len/2, freq, mag);
		SetRange(gcf->ax[1], 'x', 0, fs/2);
		SetTick(gcf->ax[1], 'x', 0, 1000, 0, 0, "%2.0lfk", 0.001);
		SetRange(gcf->ax[1], 'y', getMean(len/2,mag)-40, ylim);
		SetTick(gcf->ax[1], 'y', 0, 10);
		gcf->ax[1]->m_ln[0]->color = gcf->ax[0]->m_ln[0]->color;
		if (multi) 
		{
			PlotDouble(gcf->ax[1], len/2, freq, mag2);
			gcf->ax[1]->m_ln[1]->color = gcf->ax[0]->m_ln[1]->color;
			delete[] fft2;
			delete[] mag2;
		}
		delete[] freq;
		delete[] fft;
		delete[] mag;
		break;
	case IDM_WAVWRITE:
		char fname[MAX_PATH];
		CFileDlg fileDlg;
		fileDlg.InitFileDlg(hDlg, hInst, "");
		errstr[0]=0;
		if(!GetSignalInRange(signal,1))
		{	MessageBox (errStr);	return;	}
		if (fileDlg.FileSaveDlg(fullfname, fname, "Wav file (*.WAV)\0*.wav\0", "wav"))
			if (!signal.Wavwrite(fullfname, errstr))	
			{MessageBox (errstr);}
		else
		{
			CStdString str;
			if (GetLastError()!=0) { GetLastErrorStr(str); MessageBox (str.c_str(), "Filesave error");}
		}
		return;
	}
	InvalidateRect(NULL);
}