0

Please tell me, I want to write json to shared memory. StrPCopy if the text is more than 2047 character error "Access violation at 0x004074ba: address entry 0x00381000". I did not find information about the restrictions. Maybe there is another way to write json?

var
    SecurityAttr: TSecurityAttributes;
    SecurityDescr: TSecurityDescriptor;
begin
    InitializeSecurityDescriptor(@SecurityDescr,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(@SecurityDescr,True,nil,False);
    SecurityAttr.nLength:=SizeOf(TSecurityAttributes);
    SecurityAttr.lpSecurityDescriptor:=@SecurityDescr;
    SecurityAttr.bInheritHandle:=True;

    SendMMF := CreateFileMapping($FFFFFFFF, @SecurityAttr, PAGE_READWRITE, 0, 32,PChar('Global\Test'));

    if (SendMMF = 0) then
     Exit;

    SendData := MapViewOfFile(SendMMF, FILE_MAP_WRITE, 0, 0, 0);

    if SendData = nil then
        Exit;


    StrPCopy(SendData, GetJson);

    if Assigned(SendData) then
        Exit;

    if SendMMF.Size > 0 then
        Exit;

    UnmapViewOfFile(SendData);
    SendData := nil;
    CloseHandle(SendMMF);
end;

Test case

zig8953
  • 47
  • 1
  • 9
  • 2
    Why are you allocating only 32 bytes if you want to write more than 2000 characters? – Olivier Jan 27 '21 at 12:09
  • 1
    You ask for 32 byes, but a whole page is reserved, 4096 bytes, and you get an AV when you go outside that page. – David Heffernan Jan 27 '21 at 12:27
  • `After a file mapping object is created, the size of the file must not exceed the size of the file mapping object; if it does, not all of the file contents are available for sharing.` [MSDN](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga#remarks) – J... Jan 27 '21 at 13:03
  • Also take careful note : `If an application specifies a size for the file mapping object that is larger than the size of the actual named file on disk and if the page protection allows write access (that is, the flProtect parameter specifies PAGE_READWRITE or PAGE_EXECUTE_READWRITE), then the file on disk is increased to match the specified size of the file mapping object. If the file is extended, the contents of the file between the old end of the file and the new end of the file are not guaranteed to be zero; ` – J... Jan 27 '21 at 13:04
  • Also take note : `If [dwMaximumSizeLow] and dwMaximumSizeHigh are 0 (zero), the maximum size of the file mapping object is equal to the current size of the file that hFile identifies.` – J... Jan 27 '21 at 13:06
  • 1
    Also note - don't use [magic numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)) in your code. For instance, `$FFFFFFFF` for the `hFile` parameter will work in a 32bit build, but not in a 64bit build, you would need to use `$FFFFFFFFFFFFFFFF` instead. Better to use the existing `INVALID_HANDLE_VALUE` constant instead, like the documentation says to use. It has the correct value in both builds. – Remy Lebeau Jan 27 '21 at 15:49
  • 1
    Also, you need to get rid of `if Assigned(SendData) then Exit;`, it is causing you to leak the MMF and its view. Also, `if SendMMF.Size > 0 then ` should not even compile, since a `THandle` doesn't have a `Size` member. – Remy Lebeau Jan 27 '21 at 15:51

0 Answers0