Changed the loading of typelib files to use a memory mapping instead
of reading the file bit by bit.
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 3058ed8..a5b34d6 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -41,6 +41,15 @@
typedef struct ITypeLibVtbl *LPTYPELIB_VTABLE ;
#include "typelib.h"
+typedef struct tagTLBContext {
+ unsigned int oStart; /* start of TLB in file */
+ unsigned int pos; /* current pos */
+ unsigned int length; /* total length */
+ void *mapping; /* memory mapping */
+ TLBSegDir * pTblDir;
+ TLBLibInfo* pLibInfo;
+} TLBContext;
+
DEFAULT_DEBUG_CHANNEL(ole);
DECLARE_DEBUG_CHANNEL(typelib);
@@ -558,21 +567,21 @@
/* read function */
DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
{
- DWORD bytesread=0;
-
- if (( where != DO_NOT_SEEK &&
- (0xffffffff == SetFilePointer( pcx->hFile, where + pcx->oStart,
- 0,FILE_BEGIN))
- ) ||
- !ReadFile(pcx->hFile, buffer, count, &bytesread, NULL)
- ) {
- /* FIXME */
- ERR("read error is 0x%lx reading %ld bytes at 0x%lx\n",
- GetLastError(), count, where);
- TLB_abort();
- exit(1);
- }
- return bytesread;
+ if (where != DO_NOT_SEEK)
+ {
+ where += pcx->oStart;
+ if (where > pcx->length)
+ {
+ /* FIXME */
+ ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
+ TLB_abort();
+ }
+ pcx->pos = where;
+ }
+ if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
+ memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
+ pcx->pos += count;
+ return count;
}
static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
@@ -1070,23 +1079,42 @@
TLBLibInfo* pLibInfo=NULL;
TLB2Header tlbHeader;
TLBSegDir tlbSegDir;
- if((cx.hFile=OpenFile(file, &ofStruct, OF_READWRITE))==HFILE_ERROR) {
+
+ HANDLE hFile, hMap;
+ if((hFile=OpenFile(file, &ofStruct, OF_READ))==HFILE_ERROR) {
ERR("cannot open %s error 0x%lx\n",file, GetLastError());
return E_FAIL;
}
+ cx.length = SetFilePointer( hFile, 0, NULL, FILE_END );
+ if (!(hMap = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL )))
+ {
+ CloseHandle( hFile );
+ ERR("cannot map %s error 0x%lx\n",file, GetLastError());
+ return E_FAIL;
+ }
+ CloseHandle( hFile );
+ cx.mapping = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
+ CloseHandle( hMap );
+ if (!cx.mapping)
+ {
+ ERR("cannot map view of %s error 0x%lx\n",file, GetLastError());
+ return E_FAIL;
+ }
/* get pointer to beginning of typelib data */
+ cx.pos = 0;
cx.oStart=0;
if((oStart=TLB_FindTlb(&cx))<0){
if(oStart==-1)
ERR("cannot locate typelib in %s\n",file);
else
ERR("unsupported typelib format in %s\n",file);
+ UnmapViewOfFile( cx.mapping );
return E_FAIL;
}
cx.oStart=oStart;
pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo));
if (!pLibInfo){
- CloseHandle(cx.hFile);
+ UnmapViewOfFile( cx.mapping );
return E_OUTOFMEMORY;
}
pLibInfo->lpvtbl = &tlbvt;
@@ -1108,7 +1136,7 @@
tlbSegDir.pImpInfo.res0c != 0x0F
) {
ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
- CloseHandle(cx.hFile);
+ UnmapViewOfFile( cx.mapping );
return E_FAIL;
}
/* now fill our internal data */
@@ -1220,7 +1248,7 @@
}
}
- CloseHandle(cx.hFile);
+ UnmapViewOfFile( cx.mapping );
*ppTypeLib=(LPTYPELIB)pLibInfo;
return S_OK;
}
diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h
index e328ce9..9b8a57b 100644
--- a/dlls/oleaut32/typelib.h
+++ b/dlls/oleaut32/typelib.h
@@ -343,14 +343,4 @@
/*---------------------------END--------------------------------------------*/
-
-typedef struct tagTLBContext {
- HANDLE hFile; /* open typelib file */
- long oStart; /* start of TLB in file */
- TLBSegDir * pTblDir;
- TLBLibInfo* pLibInfo;
-} TLBContext;
-
-
#endif
-