示例#1
0
 int compareVersion(string version1, string version2) {
     const char * p1 = version1.c_str(), * p2 = version2.c_str();
     while (*p1 || *p2) {
         int v1 = getVer(p1), v2 = getVer(p2);
         if (v1 == -1 && v2 == -1) return 0;
         
         if (v1 == -1) v1 = 0;
         if (v2 == -1) v2 = 0;
         
         if (v1 > v2) return 1;
         if (v1 < v2) return -1;
     }
 }
示例#2
0
 int compareVersion(string version1, string version2) {
     int p1 = 0, p2 = 0;
     
     while (true) {
         int v1 = getVer(version1, p1), v2 = getVer(version2, p2);
         
         if (v1 == -1 && v2 == -1) return 0;
         
         if (v1 == -1) v1 = 0;
         if (v2 == -1) v2 = 0;
         
         if (v1 > v2) return 1;
         if (v1 < v2) return -1;
     }
 }
LRESULT CALLBACK AboutProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM)
{
	char buf[48];
	DWORD d;

	switch(message){
		case WM_INITDIALOG:
			setDlgTexts(hWnd, 11);
			d=getVer();
			sprintf(buf, "%d.%d", HIWORD(d), LOWORD(d));
			SetDlgItemTextA(hWnd, 101, buf);
			return TRUE;

		case WM_COMMAND:
			switch(wParam){
				case IDOK:
				case IDCANCEL:
					EndDialog(hWnd, wParam);
					return TRUE;
				case 123:
					GetDlgItemTextA(hWnd, wParam, buf, sizeA(buf)-13);
					if(!_tcscmp(lang, _T("English"))) strcat(buf, "/indexEN.html");
					ShellExecuteA(0, 0, buf, 0, 0, SW_SHOWNORMAL);
					break;
			}
			break;
	}
	return FALSE;
}
示例#4
0
PINFOCOPYDLL_API LPCWSTR __stdcall version()
{
	static _TCHAR _version[256];
	_tcsset_s(_version,'\0',sizeof(_version));
	_tcscpy_s(_version, getVer());
	_tcscat_s(_version, L"(DLL Ver." VER_STR_PRODUCTVERSION L" " VER_STR_LEGALCOPYRIGHT L")");
	return _version;
}
示例#5
0
 int compareVersion(string version1, string version2) {
     int len1 = version1.length(), len2 = version2.length();
     int i1 = 0, i2 = 0, v1, v2;
     
     while (i1 < len1 && i2 < len2) {
         v1 = getVer(version1, i1);
         v2 = getVer(version2, i2);
         if (v1 > v2) return 1;
         if (v1 < v2) return -1;
     }
     
     while (i1 < len1) {
         v1 = getVer(version1, i1);
         if (v1 > 0) return 1;
     }
     while (i2 < len2) {
         v2 = getVer(version2, i2);
         if (v2 > 0) return -1;
     }
     
     return 0;
 }
示例#6
0
文件: myfunc.c 项目: xunen/publicwrt
static int getVersion() {
	char file[0x100], *p;
	DWORD ver;
	strcpy(file, dataFile);
	if ((p=strrchr(file, '/')+1) == (void *)1)
		p = file;
	strcpy(p, "8021x.exe");
	if ((ver=getVer(file)) == (DWORD)-1)
		return -1;
	p = (char *)&ver;
	version[0] = p[2];
	version[1] = p[0];
	bufType = 1;
	return 0;
}
示例#7
0
文件: main.cpp 项目: mimaun/Rose
    GLBox()
    {
        //sf::err().rdbuf(NULL); //hide errors
        
#ifdef __APPLE__
        //int nullFD = open("/dev/null", O_WRONLY);
        //int oldFD = dup(2); // Duplicate the old file descriptor, so it can be restored
        //dup2(nullFD, 2); // Redirect
#endif
        
        sf::VideoMode mode(RESOLUTION, RESOLUTION, 32);
#ifdef __linux__
        sf::ContextSettings settings(32, 0, 0, 3, 3);
#else
        sf::ContextSettings settings(0, 0, 0, 3, 3);
#endif
        sf::Window window(mode, "glver", sf::Style::Default, settings);
        float ver = getVer();
        
#ifdef __APPLE__
        //dup2(oldFD, 2); // Redirect back
        //close(oldFD); // Not needed anymore
#endif
        
        if( ver < 1.0f ) {
            printf("OpenGL is not supported.\n");
            exit(1);
        }
        printf("OpenGL version %.1f is supported.\n", ver);
        
        
        sf::Clock time;
        WorldState state;
        graphicsInit();
        
        while (state.isRunning())
        {
            this->handleEvents(window, state);
            state.timeStep( time.getElapsedTime().asSeconds() );
            display(state);
            window.display();
        }
        window.close();
    }
示例#8
0
int main(int argc, char *argv[])
{
    // Try to change the value of `OPERATION_DELAY` and see how the behavior of this program changes.
#ifndef NDEBUG
    const int OPERATION_DELAY(200);
#else
    int OPERATION_DELAY;
    if (argc < 2) {
        OPERATION_DELAY = 200;
    } else {
        try {
            OPERATION_DELAY = std::stoi(argv[1]);
        } catch (...) {
            OPERATION_DELAY = 200;
        }
    }
#endif

    std::unique_ptr<serial::Serial> serialPtr = nullptr;
    try {
        serialPtr = std::unique_ptr<serial::Serial>(new serial::Serial(GetDevicePort(), 576000));
    } catch (const std::exception &e) {
        RETURN_ON_FAILURE();
    }

    serial::Serial &serialPort = *serialPtr;

    std::function<void (std::uint8_t b0, std::uint8_t b1)> sendTwoBytesCommand = 
        [&](std::uint8_t b0, std::uint8_t b1)
        {
            std::uint8_t command[] = {b0, b1};
            if (serialPort.isOpen()) {
                serialPort.write(command, 2);
            }
        };
    std::function<void ()> start  = std::bind(sendTwoBytesCommand, 0xAA, 0xAA);
    std::function<void ()> stop   = std::bind(sendTwoBytesCommand, 0xBB, 0xBB);
    std::function<void ()> getVer = std::bind(sendTwoBytesCommand, 0xCC, 0xCC);

    std::function<void ()> reopen = [&]() 
    {
        serialPort.close();

        serialPort.open();
        if (serialPort.isOpen()) {
            std::uint8_t version[3] = {0};

            try {
                // Send a command to get the version of our device
                getVer();
                // Receive version information
                std::size_t len = serialPort.read(version, ARRAYSIZE(version));
                if (len != ARRAYSIZE(version) || version[0] != 0x50) {
                    serialPort.close();
                }
            } catch (...) {
                serialPort.close();
            }
        }
    };

    while (true) {
        try {
            if (!serialPort.isOpen()) {
                putchar('.');
                reopen();

                // *** Important
                sleepMS(OPERATION_DELAY);
            } else {
                getVer();

                std::uint8_t version[3];
                std::size_t len = serialPort.read(version, ARRAYSIZE(version));
                if (len == ARRAYSIZE(version) && version[0] == 0x50) {
                    std::printf("%#02x %#02x %#02x\n", version[0], version[1], version[2]);
                }

                // *** Important
                sleepMS(OPERATION_DELAY);
            }
        } catch (...) {
            serialPort.close();
        }
    }

    PAUSE();
    return 0;
}
示例#9
0
/*
unsigned long getCrcMK(size_t start_byte, int size)
{
	uint32_t* buf = NULL;
	buf = malloc(size * 4);							// size*4 количество байт в количеств слов 32бита
	if (!buf)
	{
		//printf("no memory\n");
		reset(7);
		return 1;
	}
	int err = flash_Read(start_byte, buf, size * 4);	// size*4 количество байт в количеств слов 32бита
	//if (err != size) reset(); указать параметр ошибки
	unsigned long resCrc = crc32(buf, size * 4); //оптимизировать 
	free(buf);
	return resCrc;
}
*/ 
int upd_module(size_t FW_AREA_START, size_t FW_AREA_END, size_t IMAGE_AREA_START, size_t FLASH_SZ, size_t FW_SIZE_NEW, size_t SECTOR_SZ)
{
	
	//ХЕШ СУММУ сперва проверить если норм то



	{
		//------------------------------------------------ чтение версии----------------------------------------------
		
		int verNewFw = getVer(FW_AREA_START, SECTOR_SZ, verSize, crcSize);	//версия новой прошивки до 99999 
		//printf("ver new = %d\n", verNewFw);
		int verOldFw = getVer(FW_AREA_START, SECTOR_SZ, verSize, 0);	//версия старой прошивки до 99999 
		//printf("ver old = %d\n", verOldFw);
		
		//--------------------------------------------crc пока не законченно-------------------------------		
		/*unsigned long crc32PC = getCrcPC(FW_AREA_START + verSize, crcSize);//сразу после версии в памяти
		tempSizeNew = SECTOR_SZ;
		while (tempSizeNew < FW_SIZE_NEW)
		{
			unsigned long crc32MK = getCrcMK((FW_AREA_START + tempSizeNew), 16);	//crc32PC
		}

		*/
		//---------------------------------дополнительные константы-----------------------------------------------------------------

		size_t NUMB_OF_SECT_NEW_FW = (FLASH_SZ - IMAGE_AREA_START) / SECTOR_SZ;// МАКС КОЛИЧЕСТВО СЕКТОРОВ НОВОГО ПРОЩИВКИ
		size_t NUMB_OF_SECT_OLD_FW = (FW_AREA_END - FW_AREA_START) / SECTOR_SZ;// МАКС КОЛИЧЕСТВО СЕКТОРОВ СТАРОЙ ПРОШИВКИ
		size_t IMAGE_AREA_FINISH = IMAGE_AREA_START;

		
		verNewFw = 2; //временно
		verOldFw = 1;
		if (verNewFw > verOldFw)
		{
			//---------------------------выделяем память под буфер размером SECTOR_SZ------------------------------
			
			char* bufData = NULL;
			bufData = malloc(SECTOR_SZ);
			if (!bufData)
			{
				//printf("no memory\n");
				reset(7);
				return 1;
			}
			//----------------------------------очищаем всю старую память занимаемую старой прошивкой------------------------------------

			erase = flash_Erase(FW_AREA_START, NUMB_OF_SECT_OLD_FW);  // sector Начальный сектор (нумерция с нуля) count Количество секторов, которые необходимо стереть.
			if (erase != 0)// если ноль ошибок нет
			{
				reset(1);
				return 1;
			}

			//-------------------до тех пор, пока реальный размер новой прошивки в памяти больше текущего считываемого сектора------------------------
			tempSizeNew = 0;
			while (tempSizeNew < FW_SIZE_NEW)
			{	//FW_SIZE_NEW			реальный размер новой прошивки
				//IMAGE_AREA_START		начальный адресс новой прошивки
				//IMAGE_AREA_FINISH		начальный адресс новой прошивки увеличивается на сектор
				//TEMP_SECTOR_SZ		временный размер сектора меняется в последнем проходе


				//---------------------------------читаем из памяти в буфер--------------------------------------------------------------------

				while (read != SECTOR_SZ)
				{
					read = flash_Read(IMAGE_AREA_START + tempSizeNew, bufData, SECTOR_SZ); // чтение C начала новой прошивки по одному сектору с указателя bufData return Количество реально считанных байт
					if (read != SECTOR_SZ)
					{
						countRead++;
						if (countRead == 2)//повторная попытка выполнить неудачна
						{
							reset(2);
							return 1;
						}
					}

				}
				countRead = 0;
				read = -1;
				//printf("Read addr = %d   ", IMAGE_AREA_START + tempSizeNew);

				//---------------------------------пишем из буфера в память-------------------------------------------------------------
				while (write != SECTOR_SZ)
				{
					write = flash_Write(FW_AREA_START + tempSizeNew, bufData, SECTOR_SZ);// запись с начала новой прошивки по одному сектору с указателя DATA return Количество реально записанных байт
					if (write != SECTOR_SZ)
					{
						erase = flash_Erase(IMAGE_AREA_FINISH, SECTOR_SZ);
						countWrite++;
						if (countWrite == 2)// повторная попытка выполнить неудачна
						{
							reset(3);
							return 1;
						}
					}
				}
				countWrite = 0;
				write = -1;
				//printf("Write addr = %d ", FW_AREA_START + tempSizeNew);
				//--------------------------переход к следующему сектору--------------------------------------------------

				tempSizeNew += SECTOR_SZ;
				countupd++;
				//printf("	countupd = %d \n", countupd);		
			}
			//printf("size FW_AREA_START + tempSizeNew + buffer  = %d \n", tempSizeNew);


			free(bufData);
			return 0;
		}
	}
}
示例#10
0
static void CheckUpdates(void *)
{
	TCHAR tszBuff[2048] = { 0 }, tszFileInfo[30] = { 0 }, tszTmpIni[MAX_PATH] = { 0 };
	char szKey[64] = { 0 };
	vector<FILEINFO> UpdateFiles;

	if (!Exists(tszRoot))
		CreateDirectory(tszRoot, NULL);
	Files.clear();
	Reminder = db_get_b(NULL, MODNAME, "Reminder", DEFAULT_REMINDER);
	FileCount = db_get_dw(NULL, MODNAME, "FileCount", DEFAULT_FILECOUNT);

	// Load files info
	ptrT tszDownloadURL(db_get_tsa(NULL, MODNAME, "File_VersionURL"));
	if (!tszDownloadURL) { // URL is not set
		Title = TranslateT("Pack Updater");
		Text = TranslateT("URL for checking updates not found.");
		if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1) && db_get_b(NULL, MODNAME, "Popups1", DEFAULT_POPUP_ENABLED)) {
			Number = 1;
			show_popup(0, Title, Text, Number, 0);
		}
		else if (db_get_b(NULL, MODNAME, "Popups1M", DEFAULT_MESSAGE_ENABLED))
			MessageBox(NULL, Text, Title, MB_ICONSTOP);
		hCheckThread = NULL;
		return;
	}
	// Download version info
	pFileUrl = (FILEURL *)mir_alloc(sizeof(*pFileUrl));
	mir_tstrncpy(pFileUrl->tszDownloadURL, tszDownloadURL, _countof(pFileUrl->tszDownloadURL));
	mir_sntprintf(tszBuff, _countof(tszBuff), _T("%s\\tmp.ini"), tszRoot);
	mir_tstrncpy(pFileUrl->tszDiskPath, tszBuff, _countof(pFileUrl->tszDiskPath));
	mir_tstrncpy(tszTmpIni, tszBuff, _countof(tszTmpIni));
	Title = TranslateT("Pack Updater");
	Text = TranslateT("Downloading version info...");
	DlgDownloadProc();
	mir_free(pFileUrl);
	if (!DlgDld) {
		hCheckThread = NULL;
		return;
	}

	for (CurrentFile = 0; CurrentFile < FileCount; CurrentFile++) {
		FILEINFO FileInfo = { _T(""), _T(""), _T(""), _T(""), _T(""), _T(""), _T(""), { _T(""), _T("") } };

		mir_snprintf(szKey, _countof(szKey), "File_%d_CurrentVersion", CurrentFile + 1);
		ptrT tszCurVer(db_get_tsa(NULL, MODNAME, szKey));
		if (tszCurVer)
			mir_tstrncpy(FileInfo.tszCurVer, tszCurVer, _countof(FileInfo.tszCurVer));
		else 
			mir_tstrncpy(FileInfo.tszCurVer, _T(""), _countof(FileInfo.tszCurVer));

		mir_snprintf(szKey, _countof(szKey), "File_%d_LastVersion", CurrentFile + 1);
		ptrT tszLastVer(db_get_tsa(NULL, MODNAME, szKey));
		if (tszLastVer)
			mir_tstrncpy(FileInfo.tszLastVer, tszLastVer, _countof(FileInfo.tszLastVer));
		else
			mir_tstrncpy(FileInfo.tszLastVer, _T(""), _countof(FileInfo.tszLastVer));

		Files.push_back(FileInfo);

		// Read version info
		mir_sntprintf(tszFileInfo, _countof(tszFileInfo), _T("FileInfo_%d"), CurrentFile + 1);
		GetPrivateProfileString(tszFileInfo, _T("FileVersion"), _T(""), Files[CurrentFile].tszNewVer, _countof(Files[CurrentFile].tszNewVer), tszTmpIni);
		GetPrivateProfileString(tszFileInfo, _T("Message"), _T(""), Files[CurrentFile].tszMessage, _countof(Files[CurrentFile].tszMessage), tszTmpIni);
		GetPrivateProfileString(tszFileInfo, _T("DownloadURL"), _T(""), Files[CurrentFile].File.tszDownloadURL, _countof(Files[CurrentFile].File.tszDownloadURL), tszTmpIni);
		GetPrivateProfileString(tszFileInfo, _T("AdvFolder"), _T(""), Files[CurrentFile].tszAdvFolder, _countof(Files[CurrentFile].tszAdvFolder), tszTmpIni);
		GetPrivateProfileString(tszFileInfo, _T("Descr"), _T(""), Files[CurrentFile].tszDescr, _countof(Files[CurrentFile].tszDescr), tszTmpIni);
		GetPrivateProfileString(tszFileInfo, _T("DiskFileName"), _T(""), tszBuff, MAX_PATH, tszTmpIni);

		if (_tcsstr(tszBuff, _T("\\"))) { //check update name
			Title = TranslateT("Pack Updater");
			Text = TranslateT("Name of Update's file is not supported.");
			if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1) && db_get_b(NULL, MODNAME, "Popups1", DEFAULT_POPUP_ENABLED)) {
				Number = 1;
				show_popup(0, Title, Text, Number, 0);
			}
			else if (db_get_b(NULL, MODNAME, "Popups1M", DEFAULT_MESSAGE_ENABLED))
				MessageBox(NULL, Text, Title, MB_ICONINFORMATION);
			continue;
		} // end check update name
		mir_tstrncpy(Files[CurrentFile].File.tszDiskPath, tszBuff, _countof(Files[CurrentFile].File.tszDiskPath));
		GetPrivateProfileString(tszFileInfo, _T("InfoURL"), _T(""), Files[CurrentFile].tszInfoURL, _countof(Files[CurrentFile].tszInfoURL), tszTmpIni);
		Files[CurrentFile].FileType = GetPrivateProfileInt(tszFileInfo, _T("FileType"), 0, tszTmpIni);
		Files[CurrentFile].Force = GetPrivateProfileInt(tszFileInfo, _T("Force"), 0, tszTmpIni);
		Files[CurrentFile].FileNum = CurrentFile + 1;

		if (Files[CurrentFile].FileType == 2) {
			if (mir_tstrcmp(Files[CurrentFile].tszAdvFolder, _T("")) == 0)
				mir_sntprintf(tszBuff, _countof(tszBuff), _T("Plugins\\%s"), Files[CurrentFile].File.tszDiskPath);
			else
				mir_sntprintf(tszBuff, _countof(tszBuff), _T("Plugins\\%s\\%s"), Files[CurrentFile].tszAdvFolder, Files[CurrentFile].File.tszDiskPath);
			TCHAR pluginFolderName[MAX_PATH];
			PathToAbsoluteT(tszBuff, pluginFolderName);
			if (!Files[CurrentFile].Force && (IsPluginDisabled(Files[CurrentFile].File.tszDiskPath) || !Exists(pluginFolderName))) //check if plugin disabled or not exists
				continue;
		}
		// Compare versions
		if (getVer(Files[CurrentFile].tszCurVer) < getVer(Files[CurrentFile].tszNewVer)) { // Yeah, we've got new version.
			VARST tszSysRoot(_T("%SystemRoot%"));
			VARST tszProgFiles(_T("%ProgramFiles%"));

			if (Files[CurrentFile].FileType != 1 && !IsUserAnAdmin() && (_tcsstr(tszRoot, tszSysRoot) || _tcsstr(tszRoot, tszProgFiles))) {
				MessageBox(NULL, TranslateT("Update is not possible!\nYou have no Administrator's rights.\nPlease run Miranda NG with Administrator's rights."), Title, MB_ICONINFORMATION);
				DeleteFile(tszTmpIni);
				hCheckThread = NULL;
				return;
			} // user have not admin's rights

			//добавить проверку на существование файла
			TCHAR tszFilePathDest[MAX_PATH] = { 0 };
			switch (Files[CurrentFile].FileType) {
			case 0:
			case 1:
				break;
			case 2: {
				VARST tszUtilRootPlug(_T("%miranda_path%\\Plugins"));
				if (mir_tstrcmp(Files[CurrentFile].tszAdvFolder, _T("")) == 0)
					mir_sntprintf(tszFilePathDest, _countof(tszFilePathDest), _T("%s\\%s"), tszUtilRootPlug, Files[CurrentFile].File.tszDiskPath);
				else
					mir_sntprintf(tszFilePathDest, _countof(tszFilePathDest), _T("%s\\%s\\%s"), tszUtilRootPlug, Files[CurrentFile].tszAdvFolder, Files[CurrentFile].File.tszDiskPath);
				}
				break;
			case 3: {
				VARST tszUtilRootIco(_T("%miranda_path%\\Icons"));
				if (mir_tstrcmp(Files[CurrentFile].tszAdvFolder, _T("")) == 0)
					mir_sntprintf(tszFilePathDest, _countof(tszFilePathDest), _T("%s\\%s"), tszUtilRootIco, Files[CurrentFile].File.tszDiskPath);
				else
					mir_sntprintf(tszFilePathDest, _countof(tszFilePathDest), _T("%s\\%s\\%s"), tszUtilRootIco, Files[CurrentFile].tszAdvFolder, Files[CurrentFile].File.tszDiskPath);
				}
				break;
			case 4:
			case 5: {
				VARST tszUtilRoot = Utils_ReplaceVarsT(_T("%miranda_path%"));
				if (mir_tstrcmp(Files[CurrentFile].tszAdvFolder, _T("")) == 0)
					mir_sntprintf(tszFilePathDest, _countof(tszFilePathDest), _T("%s\\%s"), tszUtilRoot, Files[CurrentFile].File.tszDiskPath);
				else
					mir_sntprintf(tszFilePathDest, _countof(tszFilePathDest), _T("%s\\%s\\%s"), tszUtilRoot, Files[CurrentFile].tszAdvFolder, Files[CurrentFile].File.tszDiskPath);
				}
				break;
			}//end* switch (Files[CurrentFile].FileType)

			if (Files[CurrentFile].Force || Exists(tszFilePathDest))
				UpdateFiles.push_back(Files[CurrentFile]);
			// Save last version
			mir_tstrncpy(Files[CurrentFile].tszLastVer, Files[CurrentFile].tszNewVer, _countof(Files[CurrentFile].tszLastVer));
			mir_snprintf(szKey, _countof(szKey), "File_%d_LastVersion", CurrentFile + 1);
			db_set_ts(NULL, MODNAME, szKey, Files[CurrentFile].tszLastVer);
		} // end compare versions
	} //end checking all files in for ()

	// Show dialog
	INT upd_ret = 0;
	if (UpdateFiles.size() > 0)
		upd_ret = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_UPDATE), GetDesktopWindow(), DlgUpdate, (LPARAM)&UpdateFiles);
	DeleteFile(tszTmpIni);
	if (upd_ret == IDCANCEL) {
		hCheckThread = NULL;
		return;
	}

	if (!UpdatesCount && !Silent) {
		Title = TranslateT("Pack Updater");
		Text = TranslateT("No updates found.");
		if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1) && db_get_b(NULL, MODNAME, "Popups2", DEFAULT_POPUP_ENABLED)) {
			Number = 2;
			show_popup(0, Title, Text, Number, 0);
		}
		else if (db_get_b(NULL, MODNAME, "Popups2M", DEFAULT_MESSAGE_ENABLED))
			MessageBox(NULL, Text, Title, MB_ICONINFORMATION);
	}

	if (!FileCount) {
		Title = TranslateT("Pack Updater");
		Text = TranslateT("No files for update.");
		if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1) && db_get_b(NULL, MODNAME, "Popups2", DEFAULT_POPUP_ENABLED)) {
			Number = 2;
			show_popup(0, Title, Text, Number, 0);
		}
		else if (db_get_b(NULL, MODNAME, "Popups2M", DEFAULT_MESSAGE_ENABLED))
			MessageBox(NULL, Text, Title, MB_ICONINFORMATION);
	}
	hCheckThread = NULL;
}