Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.02.2012, 21:47   #1
1234567852
Пользователь
 
Аватар для 1234567852
 
Регистрация: 06.08.2010
Сообщений: 12
Смущение WinInet работает не так как нужно!

Намутил программу, которая качает файлы из интернета.
Вот в принципе её малейшая часть, которую я могу представить на всеобщий обзор:
Код:
Program Downloader;
{$APPTYPE CONSOLE}
uses
	Windows,WinInet,SysUtils;

Var
	Session:Pointer;
	Connect:Pointer;
	
	DwBuffer:array[1..20] of char;
	DwBufferLen:DWord;
	DwIndex:DWord;
	
	FileSize:Dword;
	AvailableData:Dword;
	DataBuffer:ANSIstring;// Array of byte;
	Read:boolean;
	
	Iter:cardinal;
	ReadedData:DWord;
	
Begin

	// Обнуляем все переменные.
	for DwBufferLen:= 0 to 20 do DwBuffer[DwBufferLen]:= #0;
	DwIndex:= 0;
	FileSize:= 0;
	AvailableData:= 0;
	Iter:= 0;
	ReadedData:= 0;
	Read:= False;
	Session:=nil;
	Connect:= nil;
	SetLength(DataBuffer,0);
	DataBuffer:= '';
	//______________________________
	
	
	// Откроем сессию.
	Session:= InternetOpen(PChar('Downloader'),INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
	
	// Создадим соединение.
	Connect:=InternetOpenURL(Session, PChar('http://am07.mirror.alawar.com/AlawarRusDreamFarmRus.exe'), nil, 0, 0, 0);
	
	// Узнаем размер скачиваемого файла.
	DwBufferLen:=20;
	HttpQueryInfo(Connect, HTTP_QUERY_CONTENT_LENGTH,@DwBuffer, DwBufferLen, DwIndex);
	
	 // Сохраним размер файла.
	FileSize:=StrToInt(StrPas(@dwBuffer));
	WriteLn('Downloading Size:'+Inttostr(FileSize));
	
	// Зарезервируем память под файл.
	SetLength(DataBuffer,FileSize); 


	While True do // Запустим бесконечный цикл.
		begin
		
			// Спросим у сервера: сколько на данный момент можно скачать?
			InternetQueryDataAvailable(Connect, AvailableData, 0, 0); 
			
			// Если нет данных для немедленного скачивания, то выйдем из цикла.
			if AvailableData = 0 then break; 
			
			// Скачаем доступные данные в буфер.
			Read:=InternetReadFile(Connect, @DataBuffer[Iter], AvailableData, ReadedData);
			
			// Если не удалось скачать, то выйдем из цикла.
			if not Read then break;
			
			sleep(50); // Ограничение скорости скачки. (У меня интернет слишком быстрый)
			
		end;// <- конец бесконечного цикла.
		
	// Закроем соединение.
	InternetCloseHandle(Connect); 
	
	// Закроем сессию.
	InternetCloseHandle(Session); 
	
	// Если была ошибка то он её покажет.
	WriteLn('Error:'+InttoStr(GetLastError));
	
	// Сообщим о завершении работы.
	WriteLN('Downloading Complete');
	
	// Притормозим программу.
	ReadLn;
end.


Программа работает НО!
Она не качает в оперативную память! Она Скачивает на жёсткий диск в папку:
C:\Documents and Settings\<Скрыто>\Local Settings\Temporary Internet Files\Content.IE5\AYQTYCNG\

Допустим скачали, смотрим, скоко занимает памяти программа и опа 4 мб! (а не 76 мб). Ну ясен хрен, она записала на диск. Закрываем программу и снова открываем и токо после этого она даже не скачивает а просто считывает файл с диска в оперативную память.

Мне нужно скачать сразу в оперативную память (Пользователь не должен видеть этот файл на диске)

Ну воть и собственно вопрос: как это исправить? Мож есть какая - то другая функция? Может попробовать как то через OpenReqist?
Наштампуем троянец???

Последний раз редактировалось Stilet; 24.02.2012 в 22:59.
1234567852 вне форума Ответить с цитированием
Старый 24.02.2012, 22:30   #2
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Не поручусь, но попробуй флаги INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE
в функции
InternetOpenURL.
Отпишись, если получится, интересно.
EUGY вне форума Ответить с цитированием
Старый 25.02.2012, 01:09   #3
1234567852
Пользователь
 
Аватар для 1234567852
 
Регистрация: 06.08.2010
Сообщений: 12
По умолчанию

EUGY Спасибо, уже что-то. Вот что мы имеем:
INTERNET_FLAG_RELOAD - Файл всё равно пишется на жёсткий диск но когда он его скачает полностью, его уже не грузит в память, а заного с сервера качает.

INTERNET_FLAG_DONT_CACHE - как раз то, что нужно самого скачанного файла он не записывает на диск, но зато записывает какие то 2 файла с непонятным содержимым вот что я смог извлеч из одного из них Client UrlCache MMF Ver 5.2
а из другого
H.t.t.p://Ссылка на скачиваемый файл
Content-Type: application/octet-stream
Content-Length: 73049744
Оба файла весят примерно 600кб. Тоже не хотелось бы их иметь на диске.
Ладно, теперь основной проблемой стало то что я ведь скачиваю в буфер, а оперативки программа так и занимает 4 Мб, надо завтра проверить содержимое буфера...
Наштампуем троянец???

Последний раз редактировалось 1234567852; 25.02.2012 в 01:13. Причина: Случайно попала ненужная ссылка
1234567852 вне форума Ответить с цитированием
Старый 25.02.2012, 19:11   #4
1234567852
Пользователь
 
Аватар для 1234567852
 
Регистрация: 06.08.2010
Сообщений: 12
По умолчанию

Так, с буфером разобрался. Осталось придумать, как заставить программу не писать эти файлы журналов (теперь по 3 файла пишет) есть идеи?

Внимание программа скачивает неправильно, что она скачивала правильно добавьте в цикл самой последней строкой
"inc(Iter, ReadedData);",
и буфер поменяйте обратно на
"array of byte".
Жду идей...
Наштампуем троянец???
1234567852 вне форума Ответить с цитированием
Старый 26.02.2012, 03:57   #5
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Как ни старался, не смог сымитировать такое поведение, читает без проблем.
Потести в консоли.

Код:
#include "stdafx.h"
#include <windows.h>
#include <wininet.h>
#pragma comment (lib, "wininet.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	char * strurl = "http://am07.mirror.alawar.com/AlawarRusDreamFarmRus.exe"; 

	HINTERNET hSession = InternetOpen("Downloader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	HINTERNET hConnect = InternetOpenUrl(hSession, strurl, NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0 );

	// получить размер заголовка
	DWORD  dwInfoLen = 0;
	HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH, NULL, &dwInfoLen, NULL);

	// прочитать заголовок
	char* sHeadInfo = new char[dwInfoLen];
	HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH, sHeadInfo, &dwInfoLen, 0);

	// размер файла в байтах
	DWORD dwFileSize =  atoi(sHeadInfo);
	delete [] sHeadInfo;

	// буфер
	BYTE * pFileBuf = new BYTE[dwFileSize];
	BYTE * pBufScan =  pFileBuf;
	printf("file size: %d\n", dwFileSize);

	// читать
	DWORD dwAval, dwRead;
	while (InternetQueryDataAvailable(hConnect, &dwAval, 0, 0))
	{
		if (!InternetReadFile(hConnect, pBufScan, dwAval, &dwRead))
			break;
		if (!dwRead) 
			break;
		pBufScan += dwRead;

		//----
		char e[32];
		sprintf(e, "read bytes: %d \n",  pBufScan - pFileBuf);
		OutputDebugString(e);
	}

	// записать
	//HANDLE hFile = CreateFile("F:\\testfile", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	//DWORD dww;
	//WriteFile(hFile, pFileBuf, dwFileSize, &dww, NULL);
	//CloseHandle(hFile);

	delete [] pFileBuf;
	InternetCloseHandle(hConnect); 
	InternetCloseHandle(hSession); 

	return 0;
}

Последний раз редактировалось EUGY; 26.02.2012 в 04:01.
EUGY вне форума Ответить с цитированием
Старый 26.02.2012, 18:28   #6
1234567852
Пользователь
 
Аватар для 1234567852
 
Регистрация: 06.08.2010
Сообщений: 12
По умолчанию

Я тут посмотрел, всё, что качает через WinInet создаёт эти файлы журнала, даже тот самый DownloadMaster видимо без них никак((
а что дают эти строки?
Цитата:
// получить размер заголовка
DWORD dwInfoLen = 0;
HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH, NULL, &dwInfoLen, NULL);

// прочитать заголовок
char* sHeadInfo = new char[dwInfoLen];
HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH, sHeadInfo, &dwInfoLen, 0);
Это что, мы сначала узнаём сколько будет занимать памяти возвращаемая информация о длине файла, а потом уже узнаём длину файла?
Наштампуем троянец???
1234567852 вне форума Ответить с цитированием
Старый 26.02.2012, 18:36   #7
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Да.
Для HTTP_QUERY_CONTENT_LENGTH это может и излишне, но в общем случае так правильнее.
Я может прозевал, но у меня файлы журналов не создаются.
Ты это... ну ради смеха, убей процессы эксплорера перед тестом.
EUGY вне форума Ответить с цитированием
Старый 26.02.2012, 19:45   #8
1234567852
Пользователь
 
Аватар для 1234567852
 
Регистрация: 06.08.2010
Сообщений: 12
По умолчанию

Для того, чтоб следить какие библиотеки, файлы, сервисы и.т.п. использует какая - либо программа я использую программу Anvir.
Вот на скрине (см. вложение) видно: моя программа выделена, она что то пишет на диск (мало но пишет) я так и полнел, что это файлы журнала. и видно все файлы, которые она использует.
Изображения
Тип файла: jpg Screen.JPG (190.8 Кб, 150 просмотров)
Наштампуем троянец???
1234567852 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написал программу,работает,но не так как нужно( С++ ) Diwolf Помощь студентам 0 21.12.2011 19:47
Формула поиска не работает как нужно Uralmaster Microsoft Office Excel 2 14.02.2011 17:38
Таймер обратного отсчета работает не так как надо.. нужно найти ошибку в коде... Человек_Борща Общие вопросы Delphi 10 13.04.2010 20:06
С#.NET. Маленькая проблемка - условие не работает так , как надо Ksy Общие вопросы .NET 11 24.12.2009 21:07
Программма работает не так как ожидал бедный_студент Помощь студентам 3 13.10.2009 00:08