Question

I write some TCP-server usin WinSock 2 and I hava procedure which catch FD_READ event. In this procedure I need to parse recieved message. The code is here:

procedure TfrmMain.WndProc_OnWSANetEvent(var Msg: TMessage);
Var
  iCurrThread, n : Integer;
  i : Integer;
  temp : PChar;
  len : Integer;
  params : PChar;
  username : PChar; password : PChar;
  ind : Integer;
  tempy : PChar;
  tempn : PChar;
begin
  case WSAGetSelectEvent(Msg.LParam) of
    FD_READ :
      while True do
      begin
        if (FreeRThreads.GetCount <> 0) then
          begin
            iCurrThread := FreeRThreads.Pop;
            if (ReadThreads[iCurrThread].Terminated) then
              begin
                ReadThreads[iCurrThread].SetFSocket(Msg.WParam);
                ReadThreads[iCurrThread].Execute;

                temp := ReadThreads[iCurrThread].GetFText;
                meLog.Lines.Add(temp);

                if (copy(temp,1,2)='AU') then
                  begin
                    StrPLCopy(params, PChar(copy(temp, 7, StrToInt( copy(temp, 3, 4) ) )), 16372);
                    ind := pos(' ', params);
                    StrPLCopy(username, PChar(copy(params, 1, ind-1)), 16372);
                    StrPLCopy(password, PChar(copy(params, ind + 1, StrLen(params))), 16372);

                    StrPLCopy(tempy, PChar('AU0001y'), 14);
                    StrPLCopy(tempn, PChar('AU0001n'), 14);

                    if (username=PChar('dizpers')) then
                      if (password=PChar('admin')) then
                        send(Msg.WParam, tempy^, 14, 0)
                      else
                        send(Msg.WParam, tempn^, 14, 0)
                    else
                      send(Msg.WParam, tempn^, 14, 0);

                    meLog.Lines.Add('USER = '+username);
                    meLog.Lines.Add('PASSWORD = '+password);
                  end;



                FreeRThreads.Push(iCurrThread);
                break;
              end;
          end;
      end;
    FD_CLOSE :
      begin
        n := CSocketsCount - 1;
        for i := 0 to n do
          if (ClientSockets[i] = Msg.WParam) then
            begin
              closesocket(ClientSockets[i]);
              FreeSockets.Push(i);
              break;
            end;
      end;
  end;
end;

While debugging I have an "Acces Violation ... write of address ..." on the line

StrPLCopy(params, PChar(copy(temp, 7, StrToInt( copy(temp, 3, 4) ) )), 16372);

Plz, help me to solve this problem and understand why it's happened. TIA!

Was it helpful?

Solution

You must allocate memory for the params variable before to use StrPLCopy (the same goes for username,password,tempy,tempn)

check this sample

Var
  Dest   : PChar;
  Source : PChar;
begin
    Source:='This is a buffer to copy';
    //alloc a buffer of 1024 bytes 
    GetMem(Dest,1024);
    try
      //copy 
      StrPLCopy(Dest, Source, Length(Source));
      //do something
      Writeln(Dest);
    finally
      //free the memory
      FreeMem(Dest);
    end;
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top