Recent

Author Topic: MapViewOfFile identifier not found [windows]  (Read 6731 times)

safa

  • New Member
  • *
  • Posts: 17
MapViewOfFile identifier not found [windows]
« on: January 07, 2016, 12:38:39 am »
Hi, in order to create a map file in lazarus (installed on windows) , I need to use the function MapViewOfFile, but I get this compilation error:MapViewOfFile identifier not found, it worked fine when I was using delphi, but it doesn't in Lazarus, so do I need to add any unit in uses? what's the problem?
PS: I get the same error for "hfile" and "createfilemapping".
Thanks for answering me.
It's never too late, it's never too early, it's always the right moment.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: MapViewOfFile identifier not found [windows]
« Reply #1 on: January 07, 2016, 12:56:09 am »
Yes, you are sometimes required to include some other units in order to call the windows api functions.

It would simply be a too much of a job to maintain all supported platforms otherwise. The jedi windows units are included with fpc/lazarus.

With regards to MapViewOfFile, it is located inside unit jwawinbase.pas

I know you asked for examples in the other thread, but when doing a search on this function i came across some hits that might be able to help you.
The fp debugger units adds an implementation of mapped files as well as turbo's ipro (the latter is even a stream implementation inside ipstrms.pas).

Maybe they can be of help to you.


balazsszekely

  • Guest
Re: MapViewOfFile identifier not found [windows]
« Reply #2 on: January 07, 2016, 07:47:03 am »
Here is a basic example how to use map files in lazarus. For the sake of this demo, I did the read/write within the same process, but the idea is the same for inter process communication:
Code: Pascal  [Select][+][-]
  1. uses Windows;
  2.  
  3. const
  4.   FileMapName = '_ThisIsJustAUniqueString91231_';
  5.  
  6. type
  7.   PData = ^TData;
  8.   TData = packed record
  9.     FUniqueID : DWORD;
  10.     FName: string;
  11.     /add other data if you like
  12.   end;
  13. var
  14.   hFileMap: HANDLE;
  15.  
  16. function WriteData(const Data: TData): Boolean;
  17. var
  18.   pPData: PData;
  19. begin
  20.   Result := False;
  21.   pPData := MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TData));
  22.   if (pPData <>  nil) then
  23.   begin
  24.     pPData^.FUniqueID := Data.FUniqueID;
  25.     pPData^.FName := Data.FName;
  26.     UnmapViewOfFile(pPData);
  27.     Result := True;
  28.   end;
  29. end;
  30.  
  31. function ReadData(var Data: TData): Boolean;
  32. var
  33.   hOpenFileMap: HANDLE;
  34.   pPData: PData;
  35. begin
  36.   Result := False;
  37.   hOpenFileMap := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar(FileMapName));
  38.   if (hOpenFileMap <> 0) then
  39.   begin
  40.     pPData := MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  41.     if (pPData <>  nil) then
  42.     begin
  43.       Data.FUniqueID :=  pPData^.FUniqueID;
  44.       Data.FName :=  pPData^.FName;
  45.       Result := True;
  46.       UnmapViewOfFile(pPData);
  47.     end;
  48.     CloseHandle(hOpenFileMap);
  49.   end;
  50. end;
  51.  
  52. procedure TForm1.FormCreate(Sender: TObject);
  53. begin
  54.   hFileMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TData), PChar(FileMapName));
  55.   if hFileMap = 0 then
  56.     ShowMessage('Cannot create FileMap' + sLineBreak + SysErrorMessage(GetLastOSError));
  57. end;
  58.  
  59. procedure TForm1.FormDestroy(Sender: TObject);
  60. begin
  61.   CloseHandle(hFileMap);
  62. end;
  63.  
  64. procedure TForm1.bWriteClick(Sender: TObject);
  65. var
  66.   Data: TData;
  67. begin
  68.   if hFileMap <> 0 then
  69.   begin
  70.     Data.FUniqueID := 15;
  71.     Data.FName := 'test test test';
  72.     if WriteData(Data) then
  73.       ShowMessage('Data successfully written to filemap!');
  74.   end;
  75. end;
  76.  
  77. procedure TForm1.bReadClick(Sender: TObject);
  78. var
  79.   Data: TData;
  80. begin
  81.   if ReadData(Data) then
  82.     ShowMessage('UniqeID: ' + IntToStr(Data.FUniqueID) + sLineBreak +
  83.                 'Name   : ' +  Data.FName);
  84. end;                    
  85.  



PS: Feel free to ask questions if you like, shortly I will return with another example.

balazsszekely

  • Guest
Re: MapViewOfFile identifier not found [windows]
« Reply #3 on: January 07, 2016, 10:06:44 am »
As I promised earlier, I will post another example. Sometimes it's useful to know if a PE(Portable Executable - exe, dll) is 32 or 64 bit, without actually running it. The task is trivial in case of a running exe(see TaskManger-->Processes tab) but non-trivial otherwise.
For this purpose I used the MapViewOfFile api:
Code: Pascal  [Select][+][-]
  1. uses JwaWindows;
  2.  
  3. function GetPEType(const APath: WideString): Byte;
  4. const
  5.   PE_UNKNOWN = 0;
  6.   PE_16BIT   = 1;
  7.   PE_32BIT   = 2;
  8.   PE_64BIT   = 3;
  9. var
  10.   hFile, hFileMap: THandle;
  11.   PMapView: Pointer;
  12.   PIDH: PImageDosHeader;
  13.   PINTH: PImageNtHeaders;
  14.   Base: LongWord;
  15. begin
  16.   Result := PE_UNKNOWN;
  17.  
  18.   hFile := CreateFileW(PWideChar(APath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  19.   if hFile = INVALID_HANDLE_VALUE then
  20.   begin
  21.     CloseHandle(hFile);
  22.     Exit;
  23.   end;
  24.  
  25.   hFileMap  := CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil);
  26.   if hFileMap = 0 then
  27.   begin
  28.     CloseHandle(hFile);
  29.     CloseHandle(hFileMap);
  30.     Exit;
  31.   end;
  32.  
  33.   PMapView := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
  34.   if PMapView = nil then
  35.   begin
  36.     CloseHandle(hFile);
  37.     CloseHandle(hFileMap);
  38.     Exit;
  39.   end;
  40.  
  41.   PIDH := PImageDosHeader(PMapView);
  42.   if PIDH^.e_magic <> IMAGE_DOS_SIGNATURE then
  43.   begin
  44.     CloseHandle(hFile);
  45.     CloseHandle(hFileMap);
  46.     UnmapViewOfFile(PMapView);
  47.     Exit;
  48.   end;
  49.  
  50.   Base := LongWord(PIDH);
  51.   PINTH := PIMAGENTHEADERS(Base + LongWord(PIDH^.e_lfanew));
  52.   if PINTH^.Signature <> IMAGE_NT_SIGNATURE then
  53.   begin
  54.     CloseHandle(hFile);
  55.     CloseHandle(hFileMap);
  56.     UnmapViewOfFile(PMapView);
  57.     Exit;
  58.   end;
  59.  
  60.   if PINTH^.Signature = $4550 then
  61.   begin
  62.     case PINTH^.OptionalHeader.Magic of
  63.       $10b: Result := PE_32BIT;
  64.       $20b: Result := PE_64BIT
  65.     end;
  66.   end
  67.   else
  68.     Result := PE_16BIT;
  69.  
  70.   CloseHandle(hFile);
  71.   CloseHandle(hFileMap);
  72.   UnmapViewOfFile(PMapView);
  73. end;
  74.  
  75.  
  76. procedure TForm1.Button1Click(Sender: TObject);
  77. var
  78.   PEType: Byte;
  79. begin
  80.   PEType := GetPEType(WideString('c:\windows\notepad.exe'));
  81.   case PEType of
  82.     0: ShowMessage('unknown PE');
  83.     1: ShowMessage('16 bit PE');
  84.     2: ShowMessage('32 bit PE');
  85.     3: ShowMessage('64 bit PE');
  86.   end;
  87. end;

It should return 64 in case of 64 bit windows, 32 otherwise.

 

TinyPortal © 2005-2018